Compare commits
35 Commits
2024.5.4.0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0d8e5470e | ||
|
|
164b999de7 | ||
|
|
e6d5fc2b95 | ||
|
|
6d4380ccac | ||
|
|
8dfd4e8bd1 | ||
|
|
1404afdfa3 | ||
|
|
5857fcfae3 | ||
|
|
e09752a2d5 | ||
|
|
05772a9fc4 | ||
|
|
24ad338c60 | ||
|
|
ff0c4587eb | ||
|
|
fff63d0a9f | ||
|
|
2f838929cc | ||
|
|
4d74f5204b | ||
|
|
b42832719f | ||
|
|
aedcebc781 | ||
|
|
00a06d3e9a | ||
|
|
2055461829 | ||
|
|
723155e20c | ||
|
|
effaa3b65b | ||
|
|
e285de10f6 | ||
|
|
26db0e3e24 | ||
|
|
0b0933b6f0 | ||
|
|
3ce9c55575 | ||
|
|
ef36a11566 | ||
|
|
dea14d35af | ||
|
|
744698c99e | ||
|
|
aef4ce1c8f | ||
|
|
93ea2a55ac | ||
|
|
2ae8c3acfc | ||
|
|
53dcb3e2c6 | ||
|
|
ca384e54d6 | ||
|
|
5a1b5c828a | ||
|
|
22c59b41f0 | ||
|
|
444b3521eb |
@@ -1,17 +1,14 @@
|
|||||||
# Contributor's Guide
|
# Contributor's Guide
|
||||||
|
|
||||||
I welcome requests! Follow these steps to contribute:
|
Follow these steps to contribute:
|
||||||
|
|
||||||
1. Find an [issue](https://github.com/AAndyProgram/SCrawler/issues) that needs assistance.
|
1. Find an [issue](https://github.com/AAndyProgram/SCrawler/issues) that needs assistance.
|
||||||
1. Let me know you are working on it by posting a comment on the issue.
|
1. Let me know you're working on this by posting a comment on this issue.
|
||||||
1. If you find an error in the code, please provide a link to the file and the line number.
|
1. If you find a bug in the code, please provide a link to the file and line number.
|
||||||
1. If you have a code change suggestion, you can post a replacement code block.<!-- I also accept pull requests.-->
|
1. If you have a code change suggestion, you can post a replacement code block.<!-- I also accept pull requests.-->
|
||||||
|
|
||||||
# How to report a problem
|
# How to report a problem
|
||||||
1. Attach the **profile URLs or links** that you cannot download.
|
|
||||||
1. Attach the **LOG** if it exists.
|
**[Read here](https://github.com/AAndyProgram/SCrawler/blob/main/FAQ.md#how-to-report-a-problem)**
|
||||||
1. **Attach the environment information copied from SCrawler (click the top right info button in the main window, then the `Environment` button, then the `Copy` button, and paste the copied text into the issue).**
|
|
||||||
1. *Add screenshots to illustrate the problem (**optional**)*
|
|
||||||
|
|
||||||
# How to build from source
|
# How to build from source
|
||||||
1. Delete the `PersonalUtilities` project from the solution.
|
1. Delete the `PersonalUtilities` project from the solution.
|
||||||
@@ -30,7 +27,7 @@ I welcome requests! Follow these steps to contribute:
|
|||||||
**I'm currently not accepting requests to develop new sites.**
|
**I'm currently not accepting requests to develop new sites.**
|
||||||
|
|
||||||
1. Check [issues](https://github.com/AAndyProgram/SCrawler/issues) (open and [closed](https://github.com/AAndyProgram/SCrawler/issues?q=is%3Aissue+is%3Aclosed)) and [discussions](https://github.com/AAndyProgram/SCrawler/discussions) to find your issue. Perhaps I have already answered your request.
|
1. Check [issues](https://github.com/AAndyProgram/SCrawler/issues) (open and [closed](https://github.com/AAndyProgram/SCrawler/issues?q=is%3Aissue+is%3Aclosed)) and [discussions](https://github.com/AAndyProgram/SCrawler/discussions) to find your issue. Perhaps I have already answered your request.
|
||||||
1. If you don't find anything, create a new issue with your request. I usually reply as soon as possible (within the next few hours).
|
1. If you don't find anything, create a new issue with your request.
|
||||||
|
|
||||||
# Requirements for new site requests
|
# Requirements for new site requests
|
||||||
|
|
||||||
|
|||||||
657
Changelog.md
164
FAQ.md
@@ -1,120 +1,100 @@
|
|||||||
# Frequently asked questions
|
|
||||||
|
|
||||||
**Please read the [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) Before asking a question!**
|
**Join our Discord server**: https://discord.gg/uFNUXvFFmg
|
||||||
|
<br/>*You can get help faster there!*
|
||||||
|
|
||||||
**Also read [here](README.md) for basic information.**
|
# Docs
|
||||||
|
- Basic info: https://github.com/AAndyProgram/SCrawler/blob/main/README.md
|
||||||
|
- **GUIDE**: https://github.com/AAndyProgram/SCrawler/wiki/
|
||||||
|
- Settings: https://github.com/AAndyProgram/SCrawler/wiki/Settings
|
||||||
|
- Discord: https://discord.gg/uFNUXvFFmg
|
||||||
|
|
||||||
Most of your questions are already answered. All settings, functions, buttons and everything else described in the guide.
|
Most of your questions are already answered. All settings, functions, buttons and everything else described in the guide.
|
||||||
|
|
||||||
Any other questions I will keep in this file.
|
# Backup
|
||||||
|
I strongly recommend you to **regularly** create backup copies of the settings files. **An [example script](https://github.com/AAndyProgram/SCrawler/blob/main/Tools/ArchiveSCrawlerUsersDataFiles.bat) for this** on GitHub (you **should adapt** it to your environment, and you can use it when [SCrawler is closed](https://github.com/AAndyProgram/SCrawler/wiki/Settings#behavior)).
|
||||||
|
|
||||||
----
|
**This way you'll always have the latest backup of your settings files and can restore it if something goes wrong!**
|
||||||
|
|
||||||
#### Q: **HOW TO SETUP COOKIES**
|
# How to report a problem
|
||||||
|
1. **Post your problem [here](https://github.com/AAndyProgram/SCrawler/issues) or in the [help channel](https://discord.com/channels/1124032649682493462/1124281838056259614) on our Discord server**
|
||||||
A: https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies
|
2. Attach the **profile URLs or links** that you cannot download.
|
||||||
|
3. Attach the **LOG** if it exists.
|
||||||
----
|
4. Attach **the environment information** copied from SCrawler (click the top right info button in the main window, then the `Environment` button, then the `Copy` button, and paste the copied text into the message).
|
||||||
|
5. *Add screenshots to illustrate the problem (**optional**)*
|
||||||
#### Q: **Does this program have GUI or CLI.**
|
|
||||||
|
|
||||||
A: This is a GUI program.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **Will CLI be added in the future?**
|
|
||||||
|
|
||||||
A: NO.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **I want to add "...." site. How to request.**
|
|
||||||
|
|
||||||
<!---A: How to request a new site you can read [here](CONTRIBUTING.md#how-to-request-a-new-site)--->
|
|
||||||
**I'm currently not accepting requests to develop new sites.**
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **Site download failed.**
|
|
||||||
|
|
||||||
A: Check your credentials and **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**. If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
|
|
||||||
|
|
||||||
**You also can join our Discord server**: https://discord.gg/uFNUXvFFmg
|
|
||||||
<br/>*You can get help faster there!*
|
|
||||||
|
|
||||||
**ATTENTION! Issues without URLs will be closed without a response!**
|
**ATTENTION! Issues without URLs will be closed without a response!**
|
||||||
|
|
||||||
----
|
# Most frequently questions about SCrawler
|
||||||
|
|
||||||
#### Q: **I have set credentials but still nothing is downloading**
|
**If something doesn't download, always check the [SITE'S REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements) before asking questions!**
|
||||||
|
|
||||||
A: Click the `Start downloading` button or press `F5`
|
*How to use: find your problem in the list and read the answer.*
|
||||||
|
|
||||||
----
|
## General questions
|
||||||
|
- **PROFILES**
|
||||||
|
- I added a profile but **nothing downloaded** :arrow_forward: check your cookies and [site requirements](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements). If there are any optional fields that you don't fill in, do so. Still nothing works - [report it](#how-to-report-a-problem)!
|
||||||
|
- :exclamation: **Try to avoid Chinese/Japanese symbols in the paths.**
|
||||||
|
- User downloading failed :arrow_forward: check your credentials and **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**. If all settings are set and nothing works, [report it](#how-to-report-a-problem). **Don't forget to attach the LOG.**
|
||||||
|
- [How to redownload user](https://github.com/AAndyProgram/SCrawler/wiki#redownload-user)
|
||||||
|
- How to **add profile** to download :arrow_forward: copy the **[profile URL](https://github.com/AAndyProgram/SCrawler/wiki#add-user)** and press `Insert` or `Ctrl+Insert`. **ALWAYS PASTE THE USER PROFILE URL**. After that select this user and press `F5` or click the `Download selected` button.
|
||||||
|
- How to download **[saved posts](https://github.com/AAndyProgram/SCrawler/wiki#saved-posts)**
|
||||||
|
- **[HOW TO ADD COOKIES](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies)**
|
||||||
|
- [How to report a problem](#how-to-report-a-problem)
|
||||||
|
- I want you to **add the site** to SCrawler :arrow_forward: **I'm not currently accepting requests to add new sites**, but you can [create a plugin](https://github.com/AAndyProgram/SCrawler/wiki/Plugins) (for your site) for SCrawler.
|
||||||
|
- What language is SCrawler written in :arrow_forward: `vb.net`
|
||||||
|
- I don't know `vb.net` and I can't write a plugin :arrow_forward: you can write a plugin in `C#`
|
||||||
|
- I have a suggestion, will it be added :arrow_forward: maybe if it interested me.
|
||||||
|
- How to name files using a pattern (e.g. `Site_PostID_Name.jpg`) :arrow_forward: **there is no such functionality and there are no such plans**.
|
||||||
|
- **DON'T CHANGE THE DEFAULT SITE SETTINGS UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!** SCrawler already has all the default settings to work. You only need to add credentials (where [required](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)).
|
||||||
|
- My computer shut down while SCrawler was running and now **SCrawler won't start or some users are missing** :arrow_forward: restore user settings from [backup](#backup).
|
||||||
|
- Installation, update and configuration
|
||||||
|
- How to install: https://github.com/AAndyProgram/SCrawler#installation
|
||||||
|
- How to update: https://github.com/AAndyProgram/SCrawler#updating
|
||||||
|
- What file executes the program: **`SCrawler.exe`**
|
||||||
|
- Where to find binaries: https://github.com/AAndyProgram/SCrawler/releases/latest
|
||||||
|
- [How to build from source](https://github.com/AAndyProgram/SCrawler/blob/main/CONTRIBUTING.md#how-to-build-from-source)
|
||||||
|
- [Video how to configure](#video-how-to-configure)
|
||||||
|
- **Antivirus**
|
||||||
|
- **Antivirus detects SCrawler as a virus** :arrow_forward: SCrawler doesn't contain any viruses at all. All code is posted on GitHub. You can review it. I have nothing to hide. SCrawler just downloads pictures and videos. That's all. If you trust SCrawler, you should just add it to the antivirus exceptions, as I did. Sometimes antiviruses identify SCawler as a virus. This is usually related to the number of files being edited (users' settings files) and the number of files being downloaded. In this case, the antivirus can also remove these files, which will damage users' settings. **If you don't trust SCrawler, just delete it.**
|
||||||
|
- **Antivirus detects gallery-dl as a virus** :arrow_forward: it's a trustworthy program that is trusted by thousands of people around the world. Antiviruses identify some builds as containing viruses, but this is not true. **If you don't trust gallery-dl, you can simply delete it. But if you delete it, you won't be able to download [Twitter & Pinterest](https://github.com/AAndyProgram/SCrawler/wiki/Settings#gallery-dl).** You should decide for yourself.
|
||||||
|
|
||||||
#### Q: **Where can I find the release?**
|
## Sites questions
|
||||||
|
|
||||||
A: https://github.com/AAndyProgram/SCrawler/releases/latest
|
*How to use: find the site you need in the list and read the answer.*
|
||||||
|
|
||||||
----
|
- Reddit: don't use credentials at all or configure [OAuth](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-get-reddit-credentials). **Reddit profiles can be downloaded without any credentials at all. Subreddits require OAuth! If nothing downloads, use OAuth!** Don't use OAuth token to download saved posts (use cookies only).
|
||||||
|
- **META** (**Instagram**, Threads, Facebook): you need **cookies** and fill in **all fields**
|
||||||
|
- **Instagram [TIPS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram-tips)**
|
||||||
|
- **Instagram saved posts**: I don't consider questions like "I have 10k saved posts and only 1000 were downloaded". Download posts, remove them from saved posts, delete the `Saved posts` **settings folder**, repeat.
|
||||||
|
- TikTok: works via yt-dlp. If something doesn't download, we need to wait until yt-dlp fixes it. TikTok doesn't require cookies to download.
|
||||||
|
- Porn sites: **COOKIES**!
|
||||||
|
- ThisVid: https://github.com/AAndyProgram/SCrawler/wiki/Settings#thisvid-faq
|
||||||
|
- **OnlyFans**: cookies + **all fields** + [OF-Scraper (download the correct version that I pointed)](https://github.com/AAndyProgram/SCrawler/wiki/Settings#of-scraper) & [mp4decrypt](https://www.bento4.com/downloads/) & **DRM keys** to download DRM protected videos. [OF-Scraper support](https://github.com/AAndyProgram/SCrawler/wiki/Settings#of-scraper-support). Also read [this](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans-faq)
|
||||||
|
- **JustForFans**: **THE VIDEO ISN'T DOWNLOADING AT THE MOMENT** ([Issue](https://discord.com/channels/1124032649682493462/1205547615199039551/1231349555132366870))
|
||||||
|
|
||||||
#### Q: **How to run the program?**
|
## Other questions
|
||||||
|
|
||||||
A: Double-click `SCrawler.exe`
|
### Does the program remember the last download and check for new posts, downloading only new posts, or does the program download the entire profile every time
|
||||||
|
The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**!
|
||||||
|
|
||||||
----
|
### Does this program have a GUI or CLI, and will a CLI be added in the future
|
||||||
|
This is a GUI program and **NO**, <u>CLI will not be added</u>
|
||||||
|
|
||||||
#### Q: **Where to find binaries?**
|
### How to remove the label
|
||||||
|
There is no functionality to remove an individual label. You can open the `Labels.txt` file in the program settings folder and delete any label you want. You also can delete this file (`Labels.txt`). In this case, when SCrawler is launched, the list of labels will be populated only with existing labels (from the user data files).
|
||||||
|
|
||||||
A: https://github.com/AAndyProgram/SCrawler/releases/latest
|
### How to remove a user from the blacklist
|
||||||
|
Just add that user back to the program. In the dialog box that opens, click the `Add and remove from blacklist` button.
|
||||||
|
|
||||||
----
|
### You lost me. Your program is too complicated.
|
||||||
|
**I'm fine with that**. If the program is too complicated for you or you can't configure it, I can only suggest you find another (easier) program. I really don't mind! The program is free. I develop SCrawler for myself and publish it on GitHub because people found my program useful. If someone can't use it or doesn't like it, I'm okay with it.
|
||||||
|
|
||||||
#### Q: **Does the program remember the last download and check for new posts, downloading only new posts? Or does the program download the entire profile every time?**
|
### Add a step-by-step guide or video on how to use the program
|
||||||
|
**NO!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I'll add it. All options and their purposes are described on the wiki. The wiki also contains a description of all the settings and how to configure them. For complex settings there is a step-by-step guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I've developed a program with an intuitive interface. There is a `Settings` button, download buttons, a context menu that appears when you right-click on a user, and other controls. Anyone can use it.
|
||||||
|
|
||||||
A: The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**!
|
**There is already a [video](#video-how-to-configure) example of how to configure a site.**
|
||||||
|
|
||||||
----
|
# Video how to configure
|
||||||
|
|
||||||
#### Q: **How to redownload all data**
|
|
||||||
|
|
||||||
A: https://github.com/AAndyProgram/SCrawler/wiki#redownload-user
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **How to remove the label**
|
|
||||||
|
|
||||||
A: There is no functionality to remove an individual label. You can open the `Labels.txt` file in the program settings folder and delete any label you want. You also can delete this file (`Labels.txt`). In this case, when the program starts, the list of labels list will be updated with only existing labels (from the user data files).
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **How to remove a user from the blacklist**
|
|
||||||
|
|
||||||
A: Just add that user back to the program. In the dialog box that opens, click on the `Add and remove from blacklist` button.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **Why don't you answer how it works**
|
|
||||||
|
|
||||||
A: Because **I don't want to**. I don't want to waste my time explaining things that are already covered in the **[GUIDE](https://github.com/AAndyProgram/SCrawler/wiki)**! If you didn't bother to read the guide, why would I waste my time?! ALL FUNCTIONALITY IS DESCRIBED IN THE GUIDE. Before publishing a new release, I update the guide. If you don't respect my work, I don't waste my time.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **You lost me. Your program is too complicated.**
|
|
||||||
|
|
||||||
A: **I'm fine with that**. If the program is difficult for you or you can't configure it, I can only suggest you find another (easier) program. I really don't mind! The program is free. I am develop SCrawler for myself and publish on GitHub because people found my program useful. If someone can't use it or doesn't like it, I'm fine.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **I can't configure something**
|
|
||||||
|
|
||||||
A: I can only [suggest](#q-you-lost-me-your-program-is-too-complicated) you find another (easier) program.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
|
|
||||||
|
|
||||||
A: **NO!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.
|
|
||||||
|
|
||||||
**The following video was recorded by a user who loves SCrawler and demonstrates how to add credentials using Instagram as an example:**
|
**The following video was recorded by a user who loves SCrawler and demonstrates how to add credentials using Instagram as an example:**
|
||||||
|
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ List of available plugins:
|
|||||||
|
|
||||||
Tools:
|
Tools:
|
||||||
- [image2post](https://github.com/unknown81311/SCrawler-image2post) by @unknown81311: **get reddit post URL from file.**
|
- [image2post](https://github.com/unknown81311/SCrawler-image2post) by @unknown81311: **get reddit post URL from file.**
|
||||||
|
- [Update-SCrawler-Tools](https://github.com/cjb900/Update-SCrawler-Tools) by @cjb900: **a tool for updating third-party programs such as yt-dlp and gallery-dl**
|
||||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
BIN
ProgramScreenshots/SettingsSiteBluesky.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 53 KiB |
BIN
ProgramScreenshots/SettingsSiteOnlyFansAdditional.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 24 KiB |
48
README.md
@@ -1,4 +1,5 @@
|
|||||||
<!-- # :rainbow_flag: Happy LGBT Pride Month :tada:
|
<!--
|
||||||
|
# 🏳️🌈 Happy LGBT Pride Month 🎉
|
||||||
-->
|
-->
|
||||||
# 🏳️🌈 Social networks crawler 🏳️🌈
|
# 🏳️🌈 Social networks crawler 🏳️🌈
|
||||||
|
|
||||||
@@ -33,18 +34,19 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
|||||||

|

|
||||||
|
|
||||||
# What can program do:
|
# What can program do:
|
||||||
- Download pictures and videos from users' profiles and subreddits:
|
- Download pictures and videos from user profiles:
|
||||||
- YouTube videos, shorts, community feeds, users, artists, playlists, music, tracks;
|
- 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 videos (https://www.redgifs.com/);
|
- Redgifs images and videos (https://www.redgifs.com/);
|
||||||
- Twitter images and videos, saved (bookmarked) posts;
|
- Twitter images and videos, text, saved (bookmarked) posts, likes, communities;
|
||||||
- OnlyFans images and videos, saved (bookmarked) posts;
|
- Bluesky images and videos, text;
|
||||||
|
- OnlyFans images and videos, text, saved (bookmarked) posts, stories;
|
||||||
- JustForFans images and videos, saved (bookmarked) posts;
|
- JustForFans images and videos, saved (bookmarked) posts;
|
||||||
- Mastodon images and videos, saved (bookmarked) posts;
|
- Mastodon images and videos, saved (bookmarked) posts;
|
||||||
- Instagram images and videos, tagged posts, stories, saved posts;
|
- Instagram images and videos, text, tagged posts, stories, saved posts;
|
||||||
- Threads images and videos;
|
- Threads images and videos, text, saved posts;
|
||||||
- Facebook images and videos, stories, saved posts;
|
- Facebook images and videos, stories, saved posts;
|
||||||
- TikTok videos;
|
- TikTok images and videos;
|
||||||
- Pinterest boards, users, saved posts;
|
- Pinterest boards, users, saved posts;
|
||||||
- Imgur images, galleries and videos;
|
- Imgur images, galleries and videos;
|
||||||
- Gfycat videos;
|
- Gfycat videos;
|
||||||
@@ -57,7 +59,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
|||||||
- Download [saved posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
- Download [saved posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
||||||
- Add users from parsed channel
|
- Add users from parsed channel
|
||||||
- **Advanced user management**
|
- **Advanced user management**
|
||||||
- **Automation** ([downloading data automatically](https://github.com/AAndyProgram/SCrawler/wiki/Settings#automation) every ```X``` minutes)
|
- **Automation** ([downloading data automatically](https://github.com/AAndyProgram/SCrawler/wiki/Settings#automation) every `X` minutes)
|
||||||
- **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files and subscriptions posts)
|
- **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files and subscriptions posts)
|
||||||
- Multiple accounts support
|
- Multiple accounts support
|
||||||
- Labeling users
|
- Labeling users
|
||||||
@@ -78,16 +80,17 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
|||||||
- **YouTube Music**
|
- **YouTube Music**
|
||||||
- **Reddit**
|
- **Reddit**
|
||||||
- **Twitter**
|
- **Twitter**
|
||||||
|
- **Bluesky**
|
||||||
- **OnlyFans** *(partial support)*[^1]
|
- **OnlyFans** *(partial support)*[^1]
|
||||||
- **Mastodon**
|
|
||||||
- **Instagram**
|
- **Instagram**
|
||||||
- **Threads**
|
- **Threads**
|
||||||
- **Facebook**
|
- **Facebook**
|
||||||
- JustForFans *(partial support)*[^1]
|
- JustForFans *(partial support) ([video issue](https://discord.com/channels/1124032649682493462/1205547615199039551/1231349555132366870))*[^1]
|
||||||
|
- Mastodon *(out of support)*
|
||||||
- TikTok
|
- TikTok
|
||||||
- RedGifs
|
- RedGifs
|
||||||
- Pinterest
|
- Pinterest
|
||||||
- Imgur
|
- Imgur *(out of support)*
|
||||||
- Gfycat
|
- Gfycat
|
||||||
- LPSG
|
- LPSG
|
||||||
- **PornHub**
|
- **PornHub**
|
||||||
@@ -109,7 +112,7 @@ First, the program downloads the full profile. After the program downloads only
|
|||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
|
|
||||||
- Windows 10, 11 with NET Framework 4.6.1 or higher (v4.6.1 must be installed). You can check version compatibility with this [tool](Tools/NET.FrameworkVersion.ps1).
|
- **Windows 10, 11** with NET Framework 4.6.1 or higher (v4.6.1 must be installed). You can check version compatibility with this [tool](Tools/NET.FrameworkVersion.ps1).
|
||||||
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||||
|
|
||||||
# Guide
|
# Guide
|
||||||
@@ -131,6 +134,7 @@ First, the program downloads the full profile. After the program downloads only
|
|||||||
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||||
- [Reddit](https://github.com/AAndyProgram/SCrawler/wiki/Settings#reddit)
|
- [Reddit](https://github.com/AAndyProgram/SCrawler/wiki/Settings#reddit)
|
||||||
- [Twitter](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter)
|
- [Twitter](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter)
|
||||||
|
- [Bluesky](https://github.com/AAndyProgram/SCrawler/wiki/Settings#bluesky)
|
||||||
- [OnlyFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans)
|
- [OnlyFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans)
|
||||||
- [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#mastodon)
|
- [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#mastodon)
|
||||||
- [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram)
|
- [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram)
|
||||||
@@ -157,7 +161,7 @@ First, the program downloads the full profile. After the program downloads only
|
|||||||
|
|
||||||
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush:
|
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush:
|
||||||
|
|
||||||
**Don't put program in the ```Program Files``` system folder (this is portable program and program settings are stored in the program folder)**
|
**Don't put program in the `Program Files` system folder (this is portable program and program settings are stored in the program folder)**
|
||||||
|
|
||||||
**I highly doubt you can run SCrawler on Linux or Mac. SCrawler is a program that is heavily dependent on Windows.**
|
**I highly doubt you can run SCrawler on Linux or Mac. SCrawler is a program that is heavily dependent on Windows.**
|
||||||
|
|
||||||
@@ -183,7 +187,7 @@ The program has an intuitive interface.
|
|||||||
|
|
||||||
[](https://www.youtube.com/watch?v=XDn7zG4I700)
|
[](https://www.youtube.com/watch?v=XDn7zG4I700)
|
||||||
|
|
||||||
Just add a user profile and **click the ```Download``` button**.
|
Just add a user profile and **click the `Download` button**.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
stateDiagram
|
stateDiagram
|
||||||
@@ -215,16 +219,4 @@ F5-->[*]
|
|||||||
|
|
||||||
Discord server: https://discord.gg/uFNUXvFFmg
|
Discord server: https://discord.gg/uFNUXvFFmg
|
||||||
|
|
||||||
<!--
|
|
||||||
[e-mail](mailto:andyprogram@proton.me): andyprogram@proton.me
|
|
||||||
|
|
||||||
Matrix (Element): https://matrix.to/#/@andyprogram:matrix.org
|
|
||||||
|
|
||||||
Discord (contact the developer): andyprogram
|
|
||||||
|
|
||||||
Discord server: https://discord.gg/uFNUXvFFmg
|
|
||||||
|
|
||||||
[Wire](https://account.wire.com/user-profile/?id=93985052-cf2c-4b72-ac75-bbe3231cf544): @andyprogram
|
|
||||||
-->
|
|
||||||
|
|
||||||
[^1]: Partial support means that I don't have personal accounts on paid porn sites because I don't pay for porn. If this site has stopped downloading and you want me to fix it, please be ready to give me access to an account with at least one active subscription. Otherwise, the download from this site will not be fixed.
|
[^1]: Partial support means that I don't have personal accounts on paid porn sites because I don't pay for porn. If this site has stopped downloading and you want me to fix it, please be ready to give me access to an account with at least one active subscription. Otherwise, the download from this site will not be fixed.
|
||||||
@@ -36,8 +36,22 @@ Namespace Plugin.Attributes
|
|||||||
Public Property IsInformationLabel As Boolean = False
|
Public Property IsInformationLabel As Boolean = False
|
||||||
''' <summary>Label text alignment.<br/>Default: <see cref="Drawing.ContentAlignment.TopCenter"/></summary>
|
''' <summary>Label text alignment.<br/>Default: <see cref="Drawing.ContentAlignment.TopCenter"/></summary>
|
||||||
Public Property LabelTextAlign As Drawing.ContentAlignment = Drawing.ContentAlignment.TopCenter
|
Public Property LabelTextAlign As Drawing.ContentAlignment = Drawing.ContentAlignment.TopCenter
|
||||||
|
Private _IsAuth As Boolean = False
|
||||||
''' <summary>This is an authorization property</summary>
|
''' <summary>This is an authorization property</summary>
|
||||||
Public Property IsAuth As Boolean = False
|
Public Property IsAuth As Boolean
|
||||||
|
Get
|
||||||
|
Return _IsAuth
|
||||||
|
End Get
|
||||||
|
Set(ByVal _IsAuth As Boolean)
|
||||||
|
Me._IsAuth = _IsAuth
|
||||||
|
If _IsAuth And String.IsNullOrEmpty(Category) Then
|
||||||
|
Category = CategoryAuth
|
||||||
|
ElseIf Not _IsAuth AndAlso Not String.IsNullOrEmpty(Category) AndAlso Category = CategoryAuth Then
|
||||||
|
Category = String.Empty
|
||||||
|
End If
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Public Const CategoryAuth As String = "Authorization"
|
||||||
Public Property Category As String = Nothing
|
Public Property Category As String = Nothing
|
||||||
Public Property InheritanceName As String = Nothing
|
Public Property InheritanceName As String = Nothing
|
||||||
''' <summary>Initialize a new property option attribute</summary>
|
''' <summary>Initialize a new property option attribute</summary>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Namespace Plugin
|
|||||||
Property Settings As ISiteSettings
|
Property Settings As ISiteSettings
|
||||||
Property AccountName As String
|
Property AccountName As String
|
||||||
Property Name As String
|
Property Name As String
|
||||||
|
Property NameTrue As String
|
||||||
Property ID As String
|
Property ID As String
|
||||||
Property Options As String
|
Property Options As String
|
||||||
Property ParseUserMediaOnly As Boolean
|
Property ParseUserMediaOnly As Boolean
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Namespace Plugin
|
|||||||
ReadOnly Property Site As String
|
ReadOnly Property Site As String
|
||||||
Property CMDEncoding As String
|
Property CMDEncoding As String
|
||||||
Property EnvironmentPrograms As IEnumerable(Of String)
|
Property EnvironmentPrograms As IEnumerable(Of String)
|
||||||
|
Property UserAgentDefault As String
|
||||||
Sub EnvironmentProgramsUpdated()
|
Sub EnvironmentProgramsUpdated()
|
||||||
Property AccountName As String
|
Property AccountName As String
|
||||||
Property Temporary As Boolean
|
Property Temporary As Boolean
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
|
|||||||
<Assembly: AssemblyDescription("Plugin provider for SCrawler")>
|
<Assembly: AssemblyDescription("Plugin provider for SCrawler")>
|
||||||
<Assembly: AssemblyCompany("AndyProgram")>
|
<Assembly: AssemblyCompany("AndyProgram")>
|
||||||
<Assembly: AssemblyProduct("SCrawler.PluginProvider")>
|
<Assembly: AssemblyProduct("SCrawler.PluginProvider")>
|
||||||
<Assembly: AssemblyCopyright("Copyright © 2024")>
|
<Assembly: AssemblyCopyright("Copyright © 2025")>
|
||||||
<Assembly: AssemblyTrademark("AndyProgram")>
|
<Assembly: AssemblyTrademark("AndyProgram")>
|
||||||
|
|
||||||
<Assembly: ComVisible(False)>
|
<Assembly: ComVisible(False)>
|
||||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2024.4.13.0")>
|
<Assembly: AssemblyVersion("2025.6.1.0")>
|
||||||
<Assembly: AssemblyFileVersion("2024.4.13.0")>
|
<Assembly: AssemblyFileVersion("2025.6.1.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ Namespace Plugin
|
|||||||
Public Property DownloadState As UserMediaStates Implements IUserMedia.DownloadState
|
Public Property DownloadState As UserMediaStates Implements IUserMedia.DownloadState
|
||||||
Public Property PostID As String Implements IUserMedia.PostID
|
Public Property PostID As String Implements IUserMedia.PostID
|
||||||
Public Property PostDate As Date? Implements IUserMedia.PostDate
|
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 SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||||
Public Property Attempts As Integer Implements IUserMedia.Attempts
|
Public Property Attempts As Integer Implements IUserMedia.Attempts
|
||||||
Public Property [Object] As Object Implements IUserMedia.Object
|
Public Property [Object] As Object Implements IUserMedia.Object
|
||||||
@@ -48,6 +51,9 @@ Namespace Plugin
|
|||||||
Property DownloadState As UserMediaStates
|
Property DownloadState As UserMediaStates
|
||||||
Property PostID As String
|
Property PostID As String
|
||||||
Property PostDate As Date?
|
Property PostDate As Date?
|
||||||
|
Property PostText As String
|
||||||
|
Property PostTextFile As String
|
||||||
|
Property PostTextFileSpecialFolder As Boolean
|
||||||
Property SpecialFolder As String
|
Property SpecialFolder As String
|
||||||
Property Attempts As Integer
|
Property Attempts As Integer
|
||||||
Property [Object] As Object
|
Property [Object] As Object
|
||||||
|
|||||||
BIN
SCrawler.Shared/Content/Icons/FilterIcon.ico
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
SCrawler.Shared/Content/Images/FilterPic.png
Normal file
|
After Width: | Height: | Size: 320 B |
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2023.12.15.0")>
|
<Assembly: AssemblyVersion("2025.6.1.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.12.15.0")>
|
<Assembly: AssemblyFileVersion("2025.6.1.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
26
SCrawler.Shared/My Project/Resources.Designer.vb
generated
@@ -26,7 +26,7 @@ Namespace My.Resources
|
|||||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||||
Friend Module Resources
|
Public Module Resources
|
||||||
|
|
||||||
Private resourceMan As Global.System.Resources.ResourceManager
|
Private resourceMan As Global.System.Resources.ResourceManager
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ Namespace My.Resources
|
|||||||
''' Returns the cached ResourceManager instance used by this class.
|
''' Returns the cached ResourceManager instance used by this class.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
<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
|
Get
|
||||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SCrawler.Resources", GetType(Resources).Assembly)
|
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.
|
''' resource lookups using this strongly typed resource class.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
<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
|
Get
|
||||||
Return resourceCulture
|
Return resourceCulture
|
||||||
End Get
|
End Get
|
||||||
@@ -59,5 +59,25 @@ Namespace My.Resources
|
|||||||
resourceCulture = value
|
resourceCulture = value
|
||||||
End Set
|
End Set
|
||||||
End Property
|
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 Module
|
||||||
End Namespace
|
End Namespace
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
@@ -60,6 +60,7 @@
|
|||||||
: and then encoded with base64 encoding.
|
: 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: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:element name="root" msdata:IsDataSet="true">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:choice maxOccurs="unbounded">
|
<xsd:choice maxOccurs="unbounded">
|
||||||
@@ -68,9 +69,10 @@
|
|||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
</xsd:sequence>
|
</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="type" type="xsd:string" />
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
<xsd:element name="assembly">
|
<xsd:element name="assembly">
|
||||||
@@ -85,9 +87,10 @@
|
|||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
<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:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
</xsd:sequence>
|
</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="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
<xsd:element name="resheader">
|
<xsd:element name="resheader">
|
||||||
@@ -109,9 +112,16 @@
|
|||||||
<value>2.0</value>
|
<value>2.0</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<resheader name="reader">
|
<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>
|
||||||
<resheader name="writer">
|
<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>
|
</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>
|
</root>
|
||||||
@@ -82,6 +82,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
@@ -123,7 +124,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="My Project\Resources.resx">
|
<EmbeddedResource Include="My Project\Resources.resx">
|
||||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
<Generator>PublicVbMyResourcesResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -147,5 +148,9 @@
|
|||||||
<Name>PersonalUtilities</Name>
|
<Name>PersonalUtilities</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Content\Icons\FilterIcon.ico" />
|
||||||
|
<Content Include="Content\Images\FilterPic.png" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -78,6 +78,17 @@ Namespace API.YouTube.Base
|
|||||||
https = 1
|
https = 1
|
||||||
m3u8 = 2
|
m3u8 = 2
|
||||||
End Enum
|
End Enum
|
||||||
|
<Editor(GetType(EnumDropDownEditor), GetType(UITypeEditor))>
|
||||||
|
Public Enum FileDateMode As Integer
|
||||||
|
None = 0
|
||||||
|
Before = 1
|
||||||
|
After = 2
|
||||||
|
End Enum
|
||||||
|
Public Enum M3U8CreationMode As Integer
|
||||||
|
Relative = 0
|
||||||
|
Absolute = 1
|
||||||
|
Both = 2
|
||||||
|
End Enum
|
||||||
Public Structure MediaObject : Implements IIndexable, IComparable(Of MediaObject)
|
Public Structure MediaObject : Implements IIndexable, IComparable(Of MediaObject)
|
||||||
Public Type As Plugin.UserMediaTypes
|
Public Type As Plugin.UserMediaTypes
|
||||||
Public ID As String
|
Public ID As String
|
||||||
@@ -125,4 +136,34 @@ Namespace API.YouTube.Base
|
|||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
End Structure
|
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
|
End Namespace
|
||||||
@@ -18,10 +18,12 @@ Namespace API.YouTube.Base
|
|||||||
Public Const TrueUrlPattern As String = "https?://[^/]*?youtube.com/[^\?/&]+((\??[^\?/&]+|/[^\?/&]+))"
|
Public Const TrueUrlPattern As String = "https?://[^/]*?youtube.com/[^\?/&]+((\??[^\?/&]+|/[^\?/&]+))"
|
||||||
'2 - type; 5 - id
|
'2 - type; 5 - id
|
||||||
Public Const UrlTypePattern As String = "(?<=https?://[^/]*?youtube.com/)((@|[^\?/&]+))([/\?]{0,1}(list=|v=|)([^\?/&]*))(?=(\S+|\Z|))"
|
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()
|
Private Sub New()
|
||||||
End Sub
|
End Sub
|
||||||
Public Shared Function StandardizeURL(ByVal URL As String) As String
|
Public Shared Function StandardizeURL(ByVal URL As String) As String
|
||||||
Try
|
Try
|
||||||
|
URL = URL.StringTrim
|
||||||
Dim isMusic As Boolean = False, isShorts As Boolean = False
|
Dim isMusic As Boolean = False, isShorts As Boolean = False
|
||||||
If Info_GetUrlType(URL, isMusic, isShorts) = YouTubeMediaType.Single Then
|
If Info_GetUrlType(URL, isMusic, isShorts) = YouTubeMediaType.Single Then
|
||||||
If Not isMusic And Not isShorts Then
|
If Not isMusic And Not isShorts Then
|
||||||
@@ -35,6 +37,7 @@ Namespace API.YouTube.Base
|
|||||||
Next
|
Next
|
||||||
data.Clear()
|
data.Clear()
|
||||||
End If
|
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}"
|
If Not val.IsEmptyString Then Return $"https://www.youtube.com/watch?v={val}"
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -45,6 +48,7 @@ Namespace API.YouTube.Base
|
|||||||
End Function
|
End Function
|
||||||
Public Shared Function StandardizeURL_Channel(ByVal URL As String, Optional ByVal Process As Boolean = True) As String
|
Public Shared Function StandardizeURL_Channel(ByVal URL As String, Optional ByVal Process As Boolean = True) As String
|
||||||
Try
|
Try
|
||||||
|
URL = URL.StringTrim
|
||||||
Dim ct As YouTubeChannelTab = YouTubeChannelTab.All
|
Dim ct As YouTubeChannelTab = YouTubeChannelTab.All
|
||||||
Dim isMusic As Boolean = False
|
Dim isMusic As Boolean = False
|
||||||
If Process AndAlso Info_GetUrlType(URL, isMusic,,,, ct) = YouTubeMediaType.Channel AndAlso Not isMusic Then
|
If Process AndAlso Info_GetUrlType(URL, isMusic,,,, ct) = YouTubeMediaType.Channel AndAlso Not isMusic Then
|
||||||
@@ -72,6 +76,7 @@ Namespace API.YouTube.Base
|
|||||||
Public Shared Function Info_GetUrlType(ByVal URL As String, Optional ByRef IsMusic As Boolean = False, Optional ByRef IsShorts As Boolean = False,
|
Public Shared Function Info_GetUrlType(ByVal URL As String, Optional ByRef IsMusic As Boolean = False, Optional ByRef IsShorts As Boolean = False,
|
||||||
Optional ByRef IsChannelUser As Boolean = False, Optional ByRef Id As String = Nothing,
|
Optional ByRef IsChannelUser As Boolean = False, Optional ByRef Id As String = Nothing,
|
||||||
Optional ByRef ChannelOptions As YouTubeChannelTab = YouTubeChannelTab.All) As YouTubeMediaType
|
Optional ByRef ChannelOptions As YouTubeChannelTab = YouTubeChannelTab.All) As YouTubeMediaType
|
||||||
|
URL = URL.StringTrim
|
||||||
If Not URL.IsEmptyString Then
|
If Not URL.IsEmptyString Then
|
||||||
IsMusic = URL.Contains("music.youtube.com")
|
IsMusic = URL.Contains("music.youtube.com")
|
||||||
IsChannelUser = False
|
IsChannelUser = False
|
||||||
@@ -97,6 +102,9 @@ Namespace API.YouTube.Base
|
|||||||
Return YouTubeMediaType.Channel
|
Return YouTubeMediaType.Channel
|
||||||
End Select
|
End Select
|
||||||
End If
|
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
|
||||||
End If
|
End If
|
||||||
Return YouTubeMediaType.Undefined
|
Return YouTubeMediaType.Undefined
|
||||||
@@ -118,6 +126,7 @@ Namespace API.YouTube.Base
|
|||||||
Optional ByVal Token As Threading.CancellationToken = Nothing, Optional ByVal Progress As IMyProgress = Nothing,
|
Optional ByVal Token As Threading.CancellationToken = Nothing, Optional ByVal Progress As IMyProgress = Nothing,
|
||||||
Optional ByVal DateAfter As Date? = Nothing, Optional ByVal DateBefore As Date? = Nothing,
|
Optional ByVal DateAfter As Date? = Nothing, Optional ByVal DateBefore As Date? = Nothing,
|
||||||
Optional ByVal ChannelOption As YouTubeChannelTab? = Nothing, Optional ByVal UrlAsIs As Boolean = False) As IYouTubeMediaContainer
|
Optional ByVal ChannelOption As YouTubeChannelTab? = Nothing, Optional ByVal UrlAsIs As Boolean = False) As IYouTubeMediaContainer
|
||||||
|
URL = URL.StringTrim
|
||||||
If URL.IsEmptyString Then Throw New ArgumentNullException("URL", "URL cannot be null")
|
If URL.IsEmptyString Then Throw New ArgumentNullException("URL", "URL cannot be null")
|
||||||
If Not MyYouTubeSettings.YTDLP.Value.Exists Then Throw New IO.FileNotFoundException("Path to 'yt-dlp.exe' not set or program not found at destination", MyYouTubeSettings.YTDLP.Value.ToString)
|
If Not MyYouTubeSettings.YTDLP.Value.Exists Then Throw New IO.FileNotFoundException("Path to 'yt-dlp.exe' not set or program not found at destination", MyYouTubeSettings.YTDLP.Value.ToString)
|
||||||
Dim urlOrig$ = URL
|
Dim urlOrig$ = URL
|
||||||
@@ -162,7 +171,7 @@ Namespace API.YouTube.Base
|
|||||||
|
|
||||||
If result Then
|
If result Then
|
||||||
container.Parse(Nothing, _CachePathDefault, isMusic, Token, Progress)
|
container.Parse(Nothing, _CachePathDefault, isMusic, Token, Progress)
|
||||||
If Not container.HasError Then container.URL = URL : container.IsShorts = isShorts : Return container
|
If Not container.HasError Then container.URL = URL.ToMusicUrl(isMusic) : container.IsShorts = isShorts : Return container
|
||||||
End If
|
End If
|
||||||
container.Dispose()
|
container.Dispose()
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Namespace API.YouTube.Base
|
|||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
<Browsable(False)> Private ReadOnly Property XML As XmlFile Implements IXMLValuesContainer.XML
|
<Browsable(False)> Private ReadOnly Property XML As XmlFile Implements IXMLValuesContainer.XML
|
||||||
<Browsable(False)> Friend ReadOnly Property DesignXml As XmlFile
|
<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)> Private Property Mode As GridUpdateModes = GridUpdateModes.OnConfirm Implements IGridValuesContainer.Mode
|
||||||
<Browsable(False), XMLVV(-1)> Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer)
|
<Browsable(False), XMLVV(-1)> Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer)
|
||||||
<Browsable(False)> Friend ReadOnly Property DownloadLocations As DownloadLocationsCollection
|
<Browsable(False)> Friend ReadOnly Property DownloadLocations As DownloadLocationsCollection
|
||||||
@@ -131,22 +132,28 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program"), DefaultValue(False)>
|
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program"), DefaultValue(False)>
|
||||||
Private Property IDownloaderSettings_OpenFolderInOtherProgram As Boolean Implements IDownloaderSettings.OpenFolderInOtherProgram
|
Private Property IDownloaderSettings_OpenFolderInOtherProgram As Boolean Implements IDownloaderSettings.OpenFolderInOtherProgram
|
||||||
Get
|
Get
|
||||||
Return OpenFolderInOtherProgram.Use
|
Return OpenFolderInOtherProgram.Attribute.ValueTemp
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal use As Boolean)
|
Set(ByVal use As Boolean)
|
||||||
OpenFolderInOtherProgram.Use = use
|
OpenFolderInOtherProgram.Attribute.ValueTemp = use
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Private Function ShouldSerializeIDownloaderSettings_OpenFolderInOtherProgram() As Boolean
|
||||||
|
Return DirectCast(OpenFolderInOtherProgram.Attribute, IGridValue).ShouldSerializeValue
|
||||||
|
End Function
|
||||||
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program (command)"),
|
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program (command)"),
|
||||||
Description("The command to open a folder."), DefaultValue("")>
|
Description("The command to open a folder."), DefaultValue("")>
|
||||||
Private Property IDownloaderSettings_OpenFolderInOtherProgram_Command As String Implements IDownloaderSettings.OpenFolderInOtherProgram_Command
|
Private Property IDownloaderSettings_OpenFolderInOtherProgram_Command As String Implements IDownloaderSettings.OpenFolderInOtherProgram_Command
|
||||||
Get
|
Get
|
||||||
Return OpenFolderInOtherProgram
|
Return OpenFolderInOtherProgram.ValueTemp
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal command As String)
|
Set(ByVal command As String)
|
||||||
OpenFolderInOtherProgram.Value = command
|
OpenFolderInOtherProgram.ValueTemp = command
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Private Function ShouldSerializeIDownloaderSettings_OpenFolderInOtherProgram_Command() As Boolean
|
||||||
|
Return DirectCast(OpenFolderInOtherProgram, IGridValue).ShouldSerializeValue
|
||||||
|
End Function
|
||||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Check new version at start")>
|
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Check new version at start")>
|
||||||
Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean)
|
Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean)
|
||||||
#End Region
|
#End Region
|
||||||
@@ -162,6 +169,9 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible, XMLVN({"Info"}), Category("Info"), DisplayName("Create description files"),
|
<Browsable(True), GridVisible, XMLVN({"Info"}), Category("Info"), DisplayName("Create description files"),
|
||||||
Description("Create video description files. Default: false.")>
|
Description("Create video description files. Default: false.")>
|
||||||
Public ReadOnly Property CreateDescriptionFiles As XMLValue(Of Boolean)
|
Public ReadOnly Property CreateDescriptionFiles As XMLValue(Of Boolean)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"Info"}, True), Category("Info"), DisplayName("Create description files: create without description"),
|
||||||
|
Description("Create a description file with the upload date, even if the description does not exist. Default: true.")>
|
||||||
|
Public ReadOnly Property CreateDescriptionFiles_CreateWithNoDescription As XMLValue(Of Boolean)
|
||||||
<Browsable(True), GridVisible, XMLVN({"Info"}, True), Category("Info"), DisplayName("Create thumbnail files (video)"),
|
<Browsable(True), GridVisible, XMLVN({"Info"}, True), Category("Info"), DisplayName("Create thumbnail files (video)"),
|
||||||
Description("Create video thumbnail files. Default: true.")>
|
Description("Create video thumbnail files. Default: true.")>
|
||||||
Public ReadOnly Property CreateThumbnails_Video As XMLValue(Of Boolean)
|
Public ReadOnly Property CreateThumbnails_Video As XMLValue(Of Boolean)
|
||||||
@@ -179,7 +189,7 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Use cookies"),
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Use cookies"),
|
||||||
Description("By default, use cookies when downloading from YouTube.")>
|
Description("By default, use cookies when downloading from YouTube.")>
|
||||||
Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean)
|
Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean)
|
||||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}, Protocols.Any), Category("Defaults"), DisplayName("Protocol"),
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}, Protocols.https), Category("Defaults"), DisplayName("Protocol"),
|
||||||
Description("Priority download protocol. Default: 'Any'")>
|
Description("Priority download protocol. Default: 'Any'")>
|
||||||
Public ReadOnly Property DefaultProtocol As XMLValue(Of Protocols)
|
Public ReadOnly Property DefaultProtocol As XMLValue(Of Protocols)
|
||||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"),
|
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"),
|
||||||
@@ -243,9 +253,24 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Program description"),
|
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Program description"),
|
||||||
Description("Add some additional info to the program info if you need")>
|
Description("Add some additional info to the program info if you need")>
|
||||||
Friend ReadOnly Property ProgramDescription As XMLValue(Of String)
|
Friend ReadOnly Property ProgramDescription As XMLValue(Of String)
|
||||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, "%"""), Category("Defaults"), DisplayName("Remove characters"),
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}, "%"""), Category("Defaults"), DisplayName("Remove characters"),
|
||||||
Description("Remove specific characters from a file name")>
|
Description("Remove specific characters from a file name")>
|
||||||
Friend ReadOnly Property FileRemoveCharacters As XMLValue(Of String)
|
Public ReadOnly Property FileRemoveCharacters As XMLValue(Of String)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}, FileDateMode.None), Category("Defaults"), DisplayName("Add date to file name"),
|
||||||
|
Description("Add the video upload date before/after the file name")>
|
||||||
|
Public ReadOnly Property FileAddDateToFileName As XMLValue(Of FileDateMode)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Add date to title: video form"),
|
||||||
|
Description("Add video upload date before video title (visual only) in the video form")>
|
||||||
|
Public ReadOnly Property FileAddDateToFileName_VideoForm As XMLValue(Of Boolean)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Add date to title: video list"),
|
||||||
|
Description("Add video upload date before video title (visual only) in the video list")>
|
||||||
|
Public ReadOnly Property FileAddDateToFileName_VideoList As XMLValue(Of Boolean)
|
||||||
|
<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
|
#End Region
|
||||||
#Region "Defaults ChannelsDownload"
|
#Region "Defaults ChannelsDownload"
|
||||||
<Browsable(True), GridVisible, XMLVN({"Defaults", "Channels"}), Category("Defaults"), DisplayName("Default download tabs for channels"),
|
<Browsable(True), GridVisible, XMLVN({"Defaults", "Channels"}), Category("Defaults"), DisplayName("Default download tabs for channels"),
|
||||||
@@ -290,9 +315,18 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 1080), Category("Defaults Video"), DisplayName("Default definition"),
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 1080), Category("Defaults Video"), DisplayName("Default definition"),
|
||||||
Description("The default maximum video resolution. -1 for max definition")>
|
Description("The default maximum video resolution. -1 for max definition")>
|
||||||
Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer)
|
Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, True), Category("Defaults Video"), DisplayName("Allow webm formats"),
|
||||||
|
Description("Allow webm formats over http if mp4 formats are not available. Default: true.")>
|
||||||
|
Public ReadOnly Property DefaultVideoAllowWebm As XMLValue(Of Boolean)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}), Category("Defaults Video"), DisplayName("Convert non-AVC codecs to AVC"),
|
||||||
|
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)"),
|
<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)
|
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"),
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}), Category("Defaults Video"), DisplayName("Include zero size formats"),
|
||||||
Description("Include formats with zero size (or undefined size).")>
|
Description("Include formats with zero size (or undefined size).")>
|
||||||
Public ReadOnly Property DefaultVideoIncludeNullSize As XMLValue(Of Boolean)
|
Public ReadOnly Property DefaultVideoIncludeNullSize As XMLValue(Of Boolean)
|
||||||
@@ -361,6 +395,15 @@ Namespace API.YouTube.Base
|
|||||||
Throw New NotImplementedException("'GetFormat' is not available in 'FpsFormatProvider'")
|
Throw New NotImplementedException("'GetFormat' is not available in 'FpsFormatProvider'")
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 30), Category("Defaults Video"), DisplayName("Highlight FPS (higher)"),
|
||||||
|
Description("Highlight frame rates higher than this value." & vbCr & "Default: 30" & vbCr & "-1 to disable")>
|
||||||
|
Public ReadOnly Property DefaultVideoHighlightFPS_H As XMLValue(Of Integer)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, -1), Category("Defaults Video"), DisplayName("Highlight FPS (lower)"),
|
||||||
|
Description("Highlight frame rates lower than this value." & vbCr & "Default: -1" & vbCr & "-1 to disable")>
|
||||||
|
Public ReadOnly Property DefaultVideoHighlightFPS_L As XMLValue(Of Integer)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}), Category("Defaults Video"), DisplayName("Add extracted MP3 to playlist"),
|
||||||
|
Description("If you also extract MP3 when download the video, add the extracted MP3 to the playlist. Default: false.")>
|
||||||
|
Public ReadOnly Property VideoPlaylist_AddExtractedMP3 As XMLValue(Of Boolean)
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Defaults Audio"
|
#Region "Defaults Audio"
|
||||||
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, "AAC"), Category("Defaults Audio"), DisplayName("Default codec"),
|
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, "AAC"), Category("Defaults Audio"), DisplayName("Default codec"),
|
||||||
@@ -383,6 +426,9 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail"),
|
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail"),
|
||||||
Description("Embed thumbnail in the audio as cover art. Default: true.")>
|
Description("Embed thumbnail in the audio as cover art. Default: true.")>
|
||||||
Public ReadOnly Property DefaultAudioEmbedThumbnail As XMLValue(Of Boolean)
|
Public ReadOnly Property DefaultAudioEmbedThumbnail As XMLValue(Of Boolean)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail (cover)"),
|
||||||
|
Description("Try embedding the playlist cover (if it exists) as cover art. Default: true.")>
|
||||||
|
Public ReadOnly Property DefaultAudioEmbedThumbnail_Cover As XMLValue(Of Boolean)
|
||||||
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail (extracted files)"),
|
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail (extracted files)"),
|
||||||
Description("Embed thumbnail in the extracted (additional file ('mp3' only)) audio as cover art. Default: true.")>
|
Description("Embed thumbnail in the extracted (additional file ('mp3' only)) audio as cover art. Default: true.")>
|
||||||
Public ReadOnly Property DefaultAudioEmbedThumbnail_ExtractedFiles As XMLValue(Of Boolean)
|
Public ReadOnly Property DefaultAudioEmbedThumbnail_ExtractedFiles As XMLValue(Of Boolean)
|
||||||
@@ -408,6 +454,9 @@ Namespace API.YouTube.Base
|
|||||||
<Browsable(True), GridVisible, XMLVN({"Playlists"}), Category("Music"), DisplayName("M3U8 Append file number"),
|
<Browsable(True), GridVisible, XMLVN({"Playlists"}), Category("Music"), DisplayName("M3U8 Append file number"),
|
||||||
Description("Add file number to file name. Default: false.")>
|
Description("Add file number to file name. Default: false.")>
|
||||||
Public ReadOnly Property MusicPlaylistCreate_M3U8_AppendNumber As XMLValue(Of Boolean)
|
Public ReadOnly Property MusicPlaylistCreate_M3U8_AppendNumber As XMLValue(Of Boolean)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"Playlists"}, M3U8CreationMode.Relative), Category("Music"), DisplayName("Create M3U8: creation mode"),
|
||||||
|
Description("Set the playlist creation mode: absolute links, relative links, or both. If 'Both' is selected, two playlists will be created. Default: 'Relative'.")>
|
||||||
|
Public ReadOnly Property MusicPlaylistCreate_CreationMode As XMLValue(Of M3U8CreationMode)
|
||||||
#End Region
|
#End Region
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Defaults Subtitles"
|
#Region "Defaults Subtitles"
|
||||||
@@ -452,6 +501,29 @@ Namespace API.YouTube.Base
|
|||||||
TypeConverter(GetType(ValueCollectionConverter)),
|
TypeConverter(GetType(ValueCollectionConverter)),
|
||||||
Description("Additional format for downloading subtitles. This means that all subtitles will be converted to the formats you choose and saved as separate files.")>
|
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)
|
Public ReadOnly Property DefaultSubtitlesFormatAddit As XMLValuesCollection(Of String)
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"DefaultsSubtitles"}), Category("Defaults Subtitles"), DisplayName("Embed subtitles"),
|
||||||
|
Description("Embed subtitles in the video (only for mp4, webm and mkv videos)")>
|
||||||
|
Public ReadOnly Property DefaultSubtitlesEmbed As XMLValue(Of Boolean)
|
||||||
|
#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
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Initializer"
|
#Region "Initializer"
|
||||||
@@ -472,6 +544,7 @@ Namespace API.YouTube.Base
|
|||||||
XML.LoadData(EDP.None)
|
XML.LoadData(EDP.None)
|
||||||
DesignXml = New XmlFile("Settings\DesignDownloader.xml", Protector.Modes.All, False)
|
DesignXml = New XmlFile("Settings\DesignDownloader.xml", Protector.Modes.All, False)
|
||||||
DesignXml.LoadData(EDP.None)
|
DesignXml.LoadData(EDP.None)
|
||||||
|
FILTER = New Controls.YTDataFilter
|
||||||
InitializeXMLValueProperties(Me)
|
InitializeXMLValueProperties(Me)
|
||||||
AddHandler ShowNotificationsEveryDownload.TempValueChanged, AddressOf ShowNotificationsEveryDownload_TempValueChanged
|
AddHandler ShowNotificationsEveryDownload.TempValueChanged, AddressOf ShowNotificationsEveryDownload_TempValueChanged
|
||||||
Cookies = New CookieKeeper
|
Cookies = New CookieKeeper
|
||||||
|
|||||||
23
SCrawler.YouTube/Controls/ButtonRC.vb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
' 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
|
||||||
|
Public Class ButtonRC : Inherits Button
|
||||||
|
Private Const WM_CONTEXTMENU As Integer = 123 '&H7B
|
||||||
|
Private Const WM_CANCELMODE As Integer = 31 '&H1F
|
||||||
|
Private Const WM_INITMENUPOPUP As Integer = 279 '&H117
|
||||||
|
Private Const SMTO_NOTIMEOUTIFNOTHUNG As Integer = 8
|
||||||
|
Protected Overrides Sub WndProc(ByRef m As Message)
|
||||||
|
If m.Msg = WM_CONTEXTMENU Or m.Msg = WM_CANCELMODE Or m.Msg = WM_INITMENUPOPUP Or m.Msg = SMTO_NOTIMEOUTIFNOTHUNG Then
|
||||||
|
m.Result = IntPtr.Zero
|
||||||
|
Else
|
||||||
|
MyBase.WndProc(m)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
With DirectCast(MyContainer, YouTubeMediaContainerBase)
|
||||||
Select Case Sender.DefaultButton
|
Select Case Sender.DefaultButton
|
||||||
Case ADB.Open
|
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,
|
.DesignXML = DesignXML,
|
||||||
.DesignXMLNodeName = SimpleArraysFormNode,
|
.DesignXMLNodeName = SimpleArraysFormNode,
|
||||||
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText,
|
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText,
|
||||||
|
|||||||
@@ -121,9 +121,10 @@ Namespace API.YouTube.Controls
|
|||||||
Me.TXT_LIMIT.Location = New System.Drawing.Point(3, 3)
|
Me.TXT_LIMIT.Location = New System.Drawing.Point(3, 3)
|
||||||
Me.TXT_LIMIT.Name = "TXT_LIMIT"
|
Me.TXT_LIMIT.Name = "TXT_LIMIT"
|
||||||
Me.TXT_LIMIT.PlaceholderEnabled = True
|
Me.TXT_LIMIT.PlaceholderEnabled = True
|
||||||
Me.TXT_LIMIT.PlaceholderText = "e.g. ABCDE"
|
Me.TXT_LIMIT.PlaceholderText = "e.g. RDAMP"
|
||||||
Me.TXT_LIMIT.Size = New System.Drawing.Size(378, 22)
|
Me.TXT_LIMIT.Size = New System.Drawing.Size(378, 22)
|
||||||
Me.TXT_LIMIT.TabIndex = 2
|
Me.TXT_LIMIT.TabIndex = 2
|
||||||
|
Me.TXT_LIMIT.Text = "RDAMP"
|
||||||
'
|
'
|
||||||
'CONTAINER_MAIN
|
'CONTAINER_MAIN
|
||||||
'
|
'
|
||||||
|
|||||||
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
@@ -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
@@ -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
|
||||||
@@ -58,6 +58,11 @@ Namespace API.YouTube.Controls
|
|||||||
If Not m.ID.IsEmptyString AndAlso m.ID.StringToLower.Contains(DRC) Then LBL_CODECS.Text &= $"{d}DRC"
|
If Not m.ID.IsEmptyString AndAlso m.ID.StringToLower.Contains(DRC) Then LBL_CODECS.Text &= $"{d}DRC"
|
||||||
If Not SelectedAudio.ID.IsEmptyString Then LBL_CODECS.Text &= $" / {SelectedAudio.Extension}{d}{SelectedAudio.Codec}{d}{SelectedAudio.Bitrate}k"
|
If Not SelectedAudio.ID.IsEmptyString Then LBL_CODECS.Text &= $" / {SelectedAudio.Extension}{d}{SelectedAudio.Codec}{d}{SelectedAudio.Bitrate}k"
|
||||||
If Not SelectedAudio.ID.IsEmptyString AndAlso SelectedAudio.ID.StringToLower.Contains(DRC) Then LBL_CODECS.Text &= $"{d}DRC"
|
If Not SelectedAudio.ID.IsEmptyString AndAlso SelectedAudio.ID.StringToLower.Contains(DRC) Then LBL_CODECS.Text &= $"{d}DRC"
|
||||||
|
|
||||||
|
If MyYouTubeSettings.DefaultVideoHighlightFPS_H > 0 AndAlso m.FPS > MyYouTubeSettings.DefaultVideoHighlightFPS_H Then _
|
||||||
|
BackColor = MyColor.DeleteBack : ForeColor = MyColor.DeleteFore
|
||||||
|
If MyYouTubeSettings.DefaultVideoHighlightFPS_L > 0 AndAlso m.FPS < MyYouTubeSettings.DefaultVideoHighlightFPS_L Then _
|
||||||
|
BackColor = MyColor.UpdateBack : ForeColor = MyColor.UpdateFore
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Dim sv% = m.Size / 1024
|
Dim sv% = m.Size / 1024
|
||||||
|
|||||||
@@ -65,14 +65,15 @@ Namespace API.YouTube.Controls
|
|||||||
Me.LBL_TIME = New System.Windows.Forms.Label()
|
Me.LBL_TIME = New System.Windows.Forms.Label()
|
||||||
Me.LBL_URL = New System.Windows.Forms.LinkLabel()
|
Me.LBL_URL = New System.Windows.Forms.LinkLabel()
|
||||||
Me.TXT_FILE = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
Me.TXT_FILE = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||||
Me.BTT_BROWSE = New System.Windows.Forms.Button()
|
Me.BTT_BROWSE = New SCrawler.API.YouTube.Controls.ButtonRC()
|
||||||
Me.BTT_DOWN = New System.Windows.Forms.Button()
|
Me.BTT_DOWN = New System.Windows.Forms.Button()
|
||||||
Me.BTT_CANCEL = New System.Windows.Forms.Button()
|
Me.BTT_CANCEL = New System.Windows.Forms.Button()
|
||||||
Me.CMB_PLS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
Me.CMB_PLS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||||
Me.BTT_PLS_BROWSE = New System.Windows.Forms.Button()
|
Me.BTT_PLS_BROWSE = New SCrawler.API.YouTube.Controls.ButtonRC()
|
||||||
Me.OPT_VIDEO = New System.Windows.Forms.RadioButton()
|
Me.OPT_VIDEO = New System.Windows.Forms.RadioButton()
|
||||||
Me.OPT_AUDIO = New System.Windows.Forms.RadioButton()
|
Me.OPT_AUDIO = New System.Windows.Forms.RadioButton()
|
||||||
Me.LBL_AUDIO_CODEC = New System.Windows.Forms.Label()
|
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_FPS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_AUDIO_BITRATE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_AUDIO_BITRATE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TP_HEADER_BASE = New System.Windows.Forms.TableLayoutPanel()
|
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
|
Me.LBL_AUDIO_CODEC.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||||
TT_MAIN.SetToolTip(Me.LBL_AUDIO_CODEC, "Output Audio Codec")
|
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
|
||||||
'
|
'
|
||||||
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.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_FPS, 0, 0)
|
||||||
TP_FPS_BITRATE.Controls.Add(Me.TXT_AUDIO_BITRATE, 1, 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.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_FPS_BITRATE.Location = New System.Drawing.Point(6, 93)
|
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.Margin = New System.Windows.Forms.Padding(6, 0, 6, 0)
|
||||||
TP_FPS_BITRATE.Name = "TP_FPS_BITRATE"
|
TP_FPS_BITRATE.Name = "TP_FPS_BITRATE"
|
||||||
TP_FPS_BITRATE.RowCount = 1
|
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.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.Size = New System.Drawing.Size(589, 28)
|
||||||
TP_FPS_BITRATE.TabIndex = 6
|
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.Location = New System.Drawing.Point(3, 2)
|
||||||
Me.TXT_FPS.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3)
|
Me.TXT_FPS.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3)
|
||||||
Me.TXT_FPS.Name = "TXT_FPS"
|
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.TabIndex = 0
|
||||||
Me.TXT_FPS.TextBoxWidthMinimal = 30
|
Me.TXT_FPS.TextBoxWidthMinimal = 30
|
||||||
'
|
'
|
||||||
@@ -593,9 +606,9 @@ Namespace API.YouTube.Controls
|
|||||||
" to change."
|
" to change."
|
||||||
Me.TXT_AUDIO_BITRATE.CaptionWidth = 75.0R
|
Me.TXT_AUDIO_BITRATE.CaptionWidth = 75.0R
|
||||||
Me.TXT_AUDIO_BITRATE.Dock = System.Windows.Forms.DockStyle.Fill
|
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.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
|
Me.TXT_AUDIO_BITRATE.TabIndex = 1
|
||||||
'
|
'
|
||||||
'TP_HEADER_BASE
|
'TP_HEADER_BASE
|
||||||
@@ -912,13 +925,14 @@ Namespace API.YouTube.Controls
|
|||||||
Private WithEvents TXT_SUBS_ADDIT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents TXT_SUBS_ADDIT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
Private WithEvents TXT_EXTRA_AUDIO_FORMATS As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents TXT_EXTRA_AUDIO_FORMATS As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
Private WithEvents TXT_FILE As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
Private WithEvents TXT_FILE As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||||
Private WithEvents BTT_BROWSE As Button
|
Private WithEvents BTT_BROWSE As SCrawler.API.YouTube.Controls.ButtonRC
|
||||||
Private WithEvents BTT_DOWN As Button
|
Private WithEvents BTT_DOWN As Button
|
||||||
Private WithEvents BTT_CANCEL As Button
|
Private WithEvents BTT_CANCEL As Button
|
||||||
Private WithEvents TP_HEADER_INFO_2 As TableLayoutPanel
|
Private WithEvents TP_HEADER_INFO_2 As TableLayoutPanel
|
||||||
Private WithEvents TXT_FPS As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents TXT_FPS As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
Private WithEvents CMB_PLS As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
Private WithEvents CMB_PLS As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||||
Private WithEvents BTT_PLS_BROWSE As Button
|
Private WithEvents BTT_PLS_BROWSE As SCrawler.API.YouTube.Controls.ButtonRC
|
||||||
Private WithEvents TXT_AUDIO_BITRATE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents TXT_AUDIO_BITRATE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
|
Private WithEvents BTT_TRIM As Button
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -139,98 +139,96 @@
|
|||||||
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
wwAADsMBx2+oZAAAAFFJREFUOE9joAr49u3bf1Lw169f50O1QgBI0MnJCY4/vP8Ix8hiILqtrQ3TEFIM
|
vAAADrwBlbxySQAAAEhJREFUOE9jYKAG+Pbt239S8NevX+djGODk5ATHH95/hGNkMRDd1taGaQgpBiAb
|
||||||
AGGYIVDtpBsAwkQbgIyR1dDWAGLwqAGD0gByMFQ7JYCBAQChNviRiQ8ETwAAAABJRU5ErkJggg==
|
QrYBIEy0AdgMo70BxOBRAwalAeRguAGUAAChNviRcuLCdwAAAABJRU5ErkJggg==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
|
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE0xJREFUeF7t
|
||||||
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
|
3X2MZWddB/BZSkspUFsoXZidOc/vnOfsTmGgARaaBgK2VkFBsIAEgkAQsX8QNJFEq39oMMEoSDREElOB
|
||||||
GlAKCkhEC4KgQlsLQkqhKi/lrYWWlxaw3dLddrerz/Q89+7dc2fbfTn3npf5fJJv2rS758z85nnOzJz5
|
EFAKCkhEAUGqQlsLQkoBlZfy1kJ5awH7QrvtbldzdndmZ597Snd37szce8/nk3xTQjsz5/zOefbO3vO9
|
||||||
nZktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
58zNAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
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
|
||||||
k/LT6hD+Mu2oR/4rgXTW/+X02r+U3woAmDTtz/GaIv5F2nH/ZHhHfpS5J+Vf01n/S9LLbhu8OgAw0dpb
|
mQO/EFTVctfezxEXtlX9vLaqX9z9s6mqC5YWF+fLrwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
8TYL5XPTmfvb0o78v/MOvWtHvybtzXzKT1Qx/n5d1wv5pQCAaXXvAUFRLLXd+3WMFzZF+cKUl7X/rIri
|
|
||||||
gsWFhbn8RwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAASUVORK5CYII=
|
AAAAAAAAAAAAYIj+H5YGIizEb/aEAAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
@@ -248,115 +246,113 @@
|
|||||||
<data name="ActionButton3.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>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
wwAADsMBx2+oZAAAAFFJREFUOE9joAr49u3bf1Lw169f50O1QgBI0MnJCY4/vP8Ix8hiILqtrQ3TEFIM
|
vAAADrwBlbxySQAAAEhJREFUOE9jYKAG+Pbt239S8NevX+djGODk5ATHH95/hGNkMRDd1taGaQgpBiAb
|
||||||
AGGYIVDtpBsAwkQbgIyR1dDWAGLwqAGD0gByMFQ7JYCBAQChNviRiQ8ETwAAAABJRU5ErkJggg==
|
QrYBIEy0AdgMo70BxOBRAwalAeRguAGUAAChNviRcuLCdwAAAABJRU5ErkJggg==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton4.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>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAeElE
|
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAAAd0lE
|
||||||
QVQ4T2P4//8/RRhMFHQfKgDi/yAaXQEhDCZAmkNbnvyXta4CciESLEws//FhmDqYAQUgzUBMngsowVgF
|
QVQ4T2P4//8/AyUYTBR0Hyoo6D70H0SjKyCEYQb8D2158l/Wuuo/TIKFieU/PoxuQAFIs6x1FXkuoARj
|
||||||
ScFgYjQQsUsQi8FEYsXyAiD+D6LRFRDCYAKk2bPo6H9J40wgFyKBLeCQMUwdzIACkGYgHnKB+J8BAD5Q
|
CJCKwcRoIGIKkoLBRGLF8oLEiuX/QTS6AkIYZsB/z6Kj/yWNM8kLRJDNIM2SxpnkuYASjCFAKgYAPlC2
|
||||||
tqhi4tzWAAAAAElFTkSuQmCC
|
qCS4LQgAAAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
|
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE0xJREFUeF7t
|
||||||
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
|
3X2MZWddB/BZSkspUFsoXZidOc/vnOfsTmGgARaaBgK2VkFBsIAEgkAQsX8QNJFEq39oMMEoSDREElOB
|
||||||
GlAKCkhEC4KgQlsLQkqhKi/lrYWWlxaw3dLddrerz/Q89+7dc2fbfTn3npf5fJJv2rS758z85nnOzJz5
|
EFAKCkhEAUGqQlsLQkoBlZfy1kJ5awH7QrvtbldzdndmZ597Snd37szce8/nk3xTQjsz5/zOefbO3vO9
|
||||||
nZktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
58zNAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
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
|
||||||
k/LT6hD+Mu2oR/4rgXTW/+X02r+U3woAmDTtz/GaIv5F2nH/ZHhHfpS5J+Vf01n/S9LLbhu8OgAw0dpb
|
mQO/EFTVctfezxEXtlX9vLaqX9z9s6mqC5YWF+fLrwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
8TYL5XPTmfvb0o78v/MOvWtHvybtzXzKT1Qx/n5d1wv5pQCAaXXvAUFRLLXd+3WMFzZF+cKUl7X/rIri
|
|
||||||
gsWFhbn8RwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
AAAASUVORK5CYII=
|
AAAAAAAAAAAAYIj+H5YGIizEb/aEAAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="LB_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<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">
|
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
vAAADrwBlbxySQAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
khP7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton10.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton10.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton11.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton11.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton12.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton12.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
vAAADrwBlbxySQAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
khP7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton13.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton13.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
|
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACM0lE
|
||||||
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
|
QVQ4T2P4//8/AyHMzicsqh6c34guDsIYAshYQFadhZmZhU1c18Yp8NCP/7LWvjHoajA0gbCwpqW7YeGs
|
||||||
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
|
FXYTD15xnHnihuuiiw98D//6777kynNuAREpnAYwMjIyqQQX9zkvffDfZce3//b7//23PPD/v/HWr//1
|
||||||
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
|
Vr74b7jm3X/VpI7FTIyMjFgNUAku6nRd//6/0ZTT31QbNlxXbthwQa3/6CO1ZS/+K8y+91968u3/qr1X
|
||||||
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
|
/gsq6jliGCCoYmRp23/4u4R9eCczF782AwMDFwMDA7OYhV+C2ooP/5UnXf+vkDXnioi+cz4LG6cIhgGK
|
||||||
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
|
zlE1/PLakcguArsquXuOSvmqayLatmnMjAx86PJwBhMzM4YkCPNKKpkxMTAIootjGIANswtKSKKLoWMM
|
||||||
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
|
ARAW0LS20S2at1POM20quhyvspGFqLlfJoYBTCzsnEI6Dl6a6ZO32c66+t91/dv/Akq6wTB5IQVdfgnP
|
||||||
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
|
jGSlpr1vuKTVPDAM4FczD7Ceeum/w6J7/y2XP/2vt/rNf9mGTUekC+eulKtYuUW+5+Qj2TlP/4u4psxD
|
||||||
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
|
dhGSC9h4dUoWntZf9e6/0qr3/5V3/Puvuu//f6Xt///Lrvr8X3ryzf8SfsWbmNBiAsV/bJIqpkpLX/xU
|
||||||
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
|
2/n3v+qcmx9VZl77oth97L1U2pQTgtq2WUwMDGzI6jEMAGFR/7wGzS3f//PIagawcvIqsLJzKTAyMLCi
|
||||||
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
|
q8NpABMLK4dCfOsSZlYOUXQ5bBgArRReBMoH61gAAAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton14.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton14.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton15.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton15.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
vAAADrwBlbxySQAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
khP7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton16.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton16.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton17.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton17.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -32,6 +32,7 @@ Namespace API.YouTube.Controls
|
|||||||
Private Initialization As Boolean = True
|
Private Initialization As Boolean = True
|
||||||
Private ReadOnly InheritsFromContainer As Boolean
|
Private ReadOnly InheritsFromContainer As Boolean
|
||||||
Private ReadOnly M3U8Files As List(Of SFile)
|
Private ReadOnly M3U8Files As List(Of SFile)
|
||||||
|
Friend Property UseCookies As Boolean = False
|
||||||
Private ReadOnly Property M3U8FilesFull As List(Of SFile)
|
Private ReadOnly Property M3U8FilesFull As List(Of SFile)
|
||||||
Get
|
Get
|
||||||
Return ListAddList(Nothing, M3U8Files, LAP.NotContainsOnly).ListAddValue(CMB_PLS.Text, LAP.NotContainsOnly)
|
Return ListAddList(Nothing, M3U8Files, LAP.NotContainsOnly).ListAddValue(CMB_PLS.Text, LAP.NotContainsOnly)
|
||||||
@@ -65,6 +66,7 @@ Namespace API.YouTube.Controls
|
|||||||
CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS)
|
CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS)
|
||||||
Me.InheritsFromContainer = InheritsFromContainer
|
Me.InheritsFromContainer = InheritsFromContainer
|
||||||
MyFieldsChecker = New FieldsChecker
|
MyFieldsChecker = New FieldsChecker
|
||||||
|
UseCookies = MyYouTubeSettings.DefaultUseCookies
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Form handlers"
|
#Region "Form handlers"
|
||||||
@@ -121,7 +123,7 @@ Namespace API.YouTube.Controls
|
|||||||
img = ImageRenderer.GetImage(SFile.GetBytesFromNet(imgUrl, EDP.ReturnValue), EDP.ReturnValue)
|
img = ImageRenderer.GetImage(SFile.GetBytesFromNet(imgUrl, EDP.ReturnValue), EDP.ReturnValue)
|
||||||
If Not img Is Nothing Then ICON_VIDEO.Image = img : ICON_VIDEO.InitialImage = img
|
If Not img Is Nothing Then ICON_VIDEO.Image = img : ICON_VIDEO.InitialImage = img
|
||||||
End If
|
End If
|
||||||
LBL_TITLE.Text = .Title
|
LBL_TITLE.Text = $"{If(MyYouTubeSettings.FileAddDateToFileName_VideoForm.Value, $"[{ .DateAdded:yyyy-MM-dd}] ", String.Empty)}{ .Title}"
|
||||||
LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
|
LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
|
||||||
TP_HEADER_INFO_2.ColumnStyles(1).Width = MeasureTextDefault(LBL_TIME.Text, LBL_TIME.Font).Width + PaddingE.GetOf({LBL_TIME}).Horizontal
|
TP_HEADER_INFO_2.ColumnStyles(1).Width = MeasureTextDefault(LBL_TIME.Text, LBL_TIME.Font).Width + PaddingE.GetOf({LBL_TIME}).Horizontal
|
||||||
TP_HEADER_INFO_2.Refresh()
|
TP_HEADER_INFO_2.Refresh()
|
||||||
@@ -227,7 +229,7 @@ Namespace API.YouTube.Controls
|
|||||||
Dim data As IEnumerable(Of Control)
|
Dim data As IEnumerable(Of Control)
|
||||||
|
|
||||||
If .HasElements Then
|
If .HasElements Then
|
||||||
data = .Elements.Select(Function(ee) New MediaItem(ee, True) With {.Dock = DockStyle.Fill, .Checked = ee.Checked})
|
data = .Elements.Select(Function(ee) New MediaItem(ee, True) With {.Dock = DockStyle.Fill, .Checked = ee.Checked, .UseCookies = UseCookies})
|
||||||
Else
|
Else
|
||||||
data = (From m As MediaObject In .Self.MediaObjects
|
data = (From m As MediaObject In .Self.MediaObjects
|
||||||
Where m.Type = __contentType
|
Where m.Type = __contentType
|
||||||
@@ -463,6 +465,9 @@ Namespace API.YouTube.Controls
|
|||||||
TXT_FILE.Text = f
|
TXT_FILE.Text = f
|
||||||
End If
|
End If
|
||||||
End Sub
|
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
|
Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick
|
||||||
Select Case Sender.DefaultButton
|
Select Case Sender.DefaultButton
|
||||||
Case ADB.Open
|
Case ADB.Open
|
||||||
@@ -610,7 +615,7 @@ Namespace API.YouTube.Controls
|
|||||||
$"Video|{AvailableVideoFormats.Select(Function(vf) $"*.{vf.ToLower}").ListToString(";")}" &
|
$"Video|{AvailableVideoFormats.Select(Function(vf) $"*.{vf.ToLower}").ListToString(";")}" &
|
||||||
$"|Audio|{AvailableAudioFormats.Select(Function(af) $"*.{af.ToLower}").ListToString(";")}"
|
$"|Audio|{AvailableAudioFormats.Select(Function(af) $"*.{af.ToLower}").ListToString(";")}"
|
||||||
f = SFile.SaveAs(f, "Select the destination of the video file",, ext, sPattern, EDP.ReturnValue)
|
f = SFile.SaveAs(f, "Select the destination of the video file",, ext, sPattern, EDP.ReturnValue)
|
||||||
f.Extension = ext
|
If Not f.IsEmptyString Then f.Extension = ext
|
||||||
End If
|
End If
|
||||||
#Enable Warning
|
#Enable Warning
|
||||||
f = CleanFileName(f)
|
f = CleanFileName(f)
|
||||||
|
|||||||
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
@@ -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
@@ -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
@@ -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
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
'
|
'
|
||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.Runtime.CompilerServices
|
||||||
Imports PersonalUtilities.Tools
|
Imports PersonalUtilities.Tools
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
@@ -53,13 +54,21 @@ Namespace API.YouTube
|
|||||||
Friend ReadOnly DateBaseProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
Friend ReadOnly DateBaseProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||||
Friend ReadOnly DateAddedProvider As New ADateTime(ADateTime.Formats.yyyymmdd) With {.DateSeparator = String.Empty}
|
Friend ReadOnly DateAddedProvider As New ADateTime(ADateTime.Formats.yyyymmdd) With {.DateSeparator = String.Empty}
|
||||||
Friend ReadOnly TimeToStringProvider As IFormatProvider = New TimeToStringConverter
|
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 TitleHtmlConverter As Func(Of String, String) = Function(Input) Input.StringRemoveWinForbiddenSymbols().StringTrim()
|
||||||
Friend ReadOnly ProgressProvider As IMyProgressNumberProvider = MyProgressNumberProvider.Percentage
|
Friend ReadOnly ProgressProvider As IMyProgressNumberProvider = MyProgressNumberProvider.Percentage
|
||||||
Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue)
|
Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue)
|
||||||
|
Friend ReadOnly MusicUrlApply As RParams = RParams.DMS("https://([w\.]*)youtube.com.+", 1, RegexReturn.Replace, EDP.ReturnValue,
|
||||||
|
CType(Function(input$) "music.", Func(Of String, String)), String.Empty)
|
||||||
|
Friend ReadOnly M3U8ExcludedSymbols As String() = {".", ",", ":", "/", "\", "(", ")", "[", "]"}
|
||||||
|
<Extension> Friend Function ToMusicUrl(ByVal URL As String, ByVal IsMusic As Boolean) As String
|
||||||
|
Try : Return If(IsMusic And Not URL.IsEmptyString, CStr(RegexReplace(URL, MusicUrlApply)).IfNullOrEmpty(URL), URL) : Catch : Return URL : End Try
|
||||||
|
End Function
|
||||||
Friend Function CleanFileName(ByVal f As SFile) As SFile
|
Friend Function CleanFileName(ByVal f As SFile) As SFile
|
||||||
If Not f.IsEmptyString And Not f.Name.IsEmptyString Then
|
If Not f.IsEmptyString And Not f.Name.IsEmptyString Then
|
||||||
Dim ff As SFile = f
|
Dim ff As SFile = f
|
||||||
ff.Name = ff.Name.StringRemoveWinForbiddenSymbols.StringTrim
|
ff.Name = ff.Name.StringRemoveWinForbiddenSymbols.StringTrim
|
||||||
|
ff.Name = ff.Name.StringReplaceSymbols({vbLf, vbCr, vbCrLf}, String.Empty, EDP.ReturnValue)
|
||||||
ff.Name = ff.Name.StringTrimEnd(".")
|
ff.Name = ff.Name.StringTrimEnd(".")
|
||||||
If Not ff.Name.IsEmptyString And Not MyYouTubeSettings.FileRemoveCharacters.IsEmptyString Then _
|
If Not ff.Name.IsEmptyString And Not MyYouTubeSettings.FileRemoveCharacters.IsEmptyString Then _
|
||||||
ff.Name = ff.Name.StringReplaceSymbols(MyYouTubeSettings.FileRemoveCharacters.Value.AsList.ListCast(Of String).ToArray, String.Empty, EDP.ReturnValue)
|
ff.Name = ff.Name.StringReplaceSymbols(MyYouTubeSettings.FileRemoveCharacters.Value.AsList.ListCast(Of String).ToArray, String.Empty, EDP.ReturnValue)
|
||||||
@@ -72,11 +81,15 @@ Namespace API.YouTube
|
|||||||
Private Class TimeToStringConverter : Implements ICustomProvider
|
Private Class TimeToStringConverter : Implements ICustomProvider
|
||||||
Private ReadOnly _Provider As New ADateTime("mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
|
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 _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
|
Private ReadOnly Property Provider(ByVal t As TimeSpan) As IFormatProvider
|
||||||
Get
|
Get
|
||||||
Return If(t.Hours > 0, _ProviderWithHours, _Provider)
|
Return If(t.Hours > 0 Or ForceHours, _ProviderWithHours, _Provider)
|
||||||
End Get
|
End Get
|
||||||
End Property
|
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,
|
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||||
If Not IsNothing(Value) Then
|
If Not IsNothing(Value) Then
|
||||||
|
|||||||
@@ -133,18 +133,25 @@ Namespace DownloadObjects.STDownloader
|
|||||||
|
|
||||||
ICON_SITE.Image = .SiteIcon
|
ICON_SITE.Image = .SiteIcon
|
||||||
LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
|
LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
|
||||||
LBL_TITLE.Text = .ToString(True)
|
LBL_TITLE.Text = $"{If(MyYouTubeSettings.FileAddDateToFileName_VideoList.Value, $"[{ .DateAdded:yyyy-MM-dd}] ", String.Empty)}{ .ToString(True)}"
|
||||||
|
Dim h%, b%
|
||||||
|
If .Self.GetType Is GetType(YouTubeMediaContainerBase) OrElse (Not .Self.GetType.BaseType Is Nothing AndAlso .Self.GetType.BaseType Is GetType(YouTubeMediaContainerBase)) Then
|
||||||
|
With DirectCast(.Self, YouTubeMediaContainerBase) : h = .HeightBase : b = .BitrateBase : End With
|
||||||
|
Else
|
||||||
|
h = .Height
|
||||||
|
b = .Bitrate
|
||||||
|
End If
|
||||||
If Not .SiteKey = YouTubeSiteKey And .ContentType = Plugin.UserMediaTypes.Picture Then
|
If Not .SiteKey = YouTubeSiteKey And .ContentType = Plugin.UserMediaTypes.Picture Then
|
||||||
LBL_INFO.Text = .File.Extension.StringToUpper
|
LBL_INFO.Text = .File.Extension.StringToUpper
|
||||||
ElseIf Not .IsMusic And Not (.MediaType = Plugin.UserMediaTypes.Audio Or .MediaType = Plugin.UserMediaTypes.AudioPre) Then
|
ElseIf Not .IsMusic And Not (.MediaType = Plugin.UserMediaTypes.Audio Or .MediaType = Plugin.UserMediaTypes.AudioPre) Then
|
||||||
If .Height > 0 Then
|
If h > 0 Then
|
||||||
LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{ .Height}p"
|
LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{h}p"
|
||||||
Else
|
Else
|
||||||
LBL_INFO.Text = .File.Extension.StringToUpper
|
LBL_INFO.Text = .File.Extension.StringToUpper
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
If .Bitrate > 0 Then
|
If b > 0 Then
|
||||||
LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{ .Bitrate}k"
|
LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{b}k"
|
||||||
Else
|
Else
|
||||||
LBL_INFO.Text = .File.Extension.StringToUpper
|
LBL_INFO.Text = .File.Extension.StringToUpper
|
||||||
End If
|
End If
|
||||||
@@ -221,7 +228,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
t = 0
|
t = 0
|
||||||
End If
|
End If
|
||||||
|
|
||||||
LBL_TITLE.Text = MyContainer.ToString(True)
|
LBL_TITLE.Text = $"{If(MyYouTubeSettings.FileAddDateToFileName_VideoList.Value, $"[{ .DateAdded:yyyy-MM-dd}] ", String.Empty)}{ .ToString(True)}"
|
||||||
|
|
||||||
If Not .SiteKey = YouTubeSiteKey Then BTT_VIEW_SETTINGS.Visible = False
|
If Not .SiteKey = YouTubeSiteKey Then BTT_VIEW_SETTINGS.Visible = False
|
||||||
|
|
||||||
@@ -430,7 +437,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Else
|
Else
|
||||||
RaiseEvent BeforeOpenEditor(Me, MyContainer)
|
RaiseEvent BeforeOpenEditor(Me, MyContainer)
|
||||||
End If
|
End If
|
||||||
Using f As New VideoOptionsForm(MyContainer, initProtected Or isFull)
|
Using f As New VideoOptionsForm(MyContainer, initProtected Or isFull) With {.UseCookies = UseCookies}
|
||||||
f.ShowDialog()
|
f.ShowDialog()
|
||||||
.Protected = IIf(f.DialogResult = DialogResult.OK, True, initProtected)
|
.Protected = IIf(f.DialogResult = DialogResult.OK, True, initProtected)
|
||||||
End Using
|
End Using
|
||||||
@@ -458,12 +465,12 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If Not MyContainer Is Nothing Then
|
If Not MyContainer Is Nothing Then
|
||||||
Dim f As Form = Nothing
|
Dim f As Form = Nothing
|
||||||
Select Case MyContainer.ObjectType
|
Select Case MyContainer.ObjectType
|
||||||
Case Base.YouTubeMediaType.Single : f = New VideoOptionsForm(MyContainer, True)
|
Case Base.YouTubeMediaType.Single : f = New VideoOptionsForm(MyContainer, True) With {.UseCookies = UseCookies}
|
||||||
Case Base.YouTubeMediaType.Channel, Base.YouTubeMediaType.PlayList
|
Case Base.YouTubeMediaType.Channel, Base.YouTubeMediaType.PlayList
|
||||||
If MyContainer.IsMusic Then
|
If MyContainer.IsMusic Then
|
||||||
f = New MusicPlaylistsForm(MyContainer)
|
f = New MusicPlaylistsForm(MyContainer)
|
||||||
Else
|
Else
|
||||||
f = New VideoOptionsForm(MyContainer, True)
|
f = New VideoOptionsForm(MyContainer, True) With {.UseCookies = UseCookies}
|
||||||
End If
|
End If
|
||||||
End Select
|
End Select
|
||||||
If Not f Is Nothing Then
|
If Not f Is Nothing Then
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.BTT_CLEAR_DONE = New System.Windows.Forms.ToolStripMenuItem()
|
Me.BTT_CLEAR_DONE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
Me.BTT_CLEAR_ALL = 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_ALL = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.BTT_SELECT_NONE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
Me.TOOLBAR_BOTTOM = New System.Windows.Forms.StatusStrip()
|
Me.TOOLBAR_BOTTOM = New System.Windows.Forms.StatusStrip()
|
||||||
Me.PR_MAIN = New System.Windows.Forms.ToolStripProgressBar()
|
Me.PR_MAIN = New System.Windows.Forms.ToolStripProgressBar()
|
||||||
Me.LBL_INFO = New System.Windows.Forms.ToolStripStatusLabel()
|
Me.LBL_INFO = New System.Windows.Forms.ToolStripStatusLabel()
|
||||||
@@ -43,6 +44,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.MENU_ADD = New System.Windows.Forms.ToolStripDropDownButton()
|
Me.MENU_ADD = New System.Windows.Forms.ToolStripDropDownButton()
|
||||||
Me.BTT_ADD = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
|
Me.BTT_ADD = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
|
||||||
Me.BTT_ADD_PLS_ARR = 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_DOWN = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_STOP = New System.Windows.Forms.ToolStripButton()
|
Me.BTT_STOP = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.SEP_LOG = New System.Windows.Forms.ToolStripSeparator()
|
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_INFO = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_DONATE = New System.Windows.Forms.ToolStripButton()
|
Me.BTT_DONATE = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_BUG_REPORT = 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_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
SEP_3 = New System.Windows.Forms.ToolStripSeparator()
|
SEP_3 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
MENU_DEL_CLEAR = New System.Windows.Forms.ToolStripDropDownButton()
|
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.Size = New System.Drawing.Size(185, 22)
|
||||||
Me.BTT_SELECT_ALL.Text = "Select all"
|
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
|
'TOOLBAR_BOTTOM
|
||||||
'
|
'
|
||||||
Me.TOOLBAR_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_MAIN, Me.LBL_INFO})
|
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
|
'TOOLBAR_TOP
|
||||||
'
|
'
|
||||||
Me.TOOLBAR_TOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
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.Location = New System.Drawing.Point(0, 0)
|
||||||
Me.TOOLBAR_TOP.Name = "TOOLBAR_TOP"
|
Me.TOOLBAR_TOP.Name = "TOOLBAR_TOP"
|
||||||
Me.TOOLBAR_TOP.Size = New System.Drawing.Size(584, 25)
|
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.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" &
|
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."
|
"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
|
'BTT_DOWN
|
||||||
'
|
'
|
||||||
@@ -286,11 +303,10 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.BTT_BUG_REPORT.Size = New System.Drawing.Size(23, 22)
|
Me.BTT_BUG_REPORT.Size = New System.Drawing.Size(23, 22)
|
||||||
Me.BTT_BUG_REPORT.Text = "Bug report"
|
Me.BTT_BUG_REPORT.Text = "Bug report"
|
||||||
'
|
'
|
||||||
'BTT_SELECT_NONE
|
'SEP_FILTER
|
||||||
'
|
'
|
||||||
Me.BTT_SELECT_NONE.Name = "BTT_SELECT_NONE"
|
Me.SEP_FILTER.Name = "SEP_FILTER"
|
||||||
Me.BTT_SELECT_NONE.Size = New System.Drawing.Size(185, 22)
|
Me.SEP_FILTER.Size = New System.Drawing.Size(6, 25)
|
||||||
Me.BTT_SELECT_NONE.Text = "Select none"
|
|
||||||
'
|
'
|
||||||
'VideoListForm
|
'VideoListForm
|
||||||
'
|
'
|
||||||
@@ -337,5 +353,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Private WithEvents BTT_CLEAR_SELECTED As ToolStripMenuItem
|
Private WithEvents BTT_CLEAR_SELECTED As ToolStripMenuItem
|
||||||
Private WithEvents BTT_SELECT_ALL As ToolStripMenuItem
|
Private WithEvents BTT_SELECT_ALL As ToolStripMenuItem
|
||||||
Private WithEvents BTT_SELECT_NONE As ToolStripMenuItem
|
Private WithEvents BTT_SELECT_NONE As ToolStripMenuItem
|
||||||
|
Public WithEvents BTT_FILTER As ToolStripButton
|
||||||
|
Public WithEvents SEP_FILTER As ToolStripSeparator
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
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">
|
<data name="BTT_DELETE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lls3
|
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAV6SURBVEhLjZVrTFNnGMcfT4Wto2dcOtRkyBzigALlcmo5
|
||||||
FeVFihZsqaBjRM2ouILiC0oUozGaaBSTJfuwfdg+bJnJnFuiyzKZMOp8ATJl4IYLAjqspfS9cNlLskjP
|
dVNwXKRowRYEGSNiRi3jXiwQqYEQTVxQkyX7sH3YPmyZicYt0WUXBEaJjkumDNxwQUCHWErpFQ5zSxbo
|
||||||
/qe0OmPZeJJfbu85z/k//z7n3Ht5NPqLimLMSUkfXV20aPiKTPbhOqn0FQxHBSb/J4ZUKvY3mez6yMKF
|
s7xd200Fxz95c9qcc37//3me9wIAAKOZmQGGiIiP+7ZsmewKD/9of1jYywCwkdz7P01Ipexv4eE3pjZv
|
||||||
fReTkw0YigERgUkaAyaT8FZR0ZdDzc1k9OxZ0tHU5L/Csp15ItFSTEfPZIWPQYZ507Z580Pu9Gky1dpK
|
HrkSGVkAAAEAsMH3wFhlpeBmZuYXE83NOH3+PHbpdK4ulu1NoekdAOD3GO0JjTPMG6bi4gdcRwcunTuH
|
||||||
hisrPe+nptbLYmPjMT1TpHPJkg/u7d1LHhw7RkaPHiVWJFsOHCBtLHtdLhK9jpSwRUbU6jUQt3BnzhAO
|
k4WF9g+io6vCAwODfSa927d/eLehAe+3t+N0WxsaOzpwpqkJO1n2hpimX1vLZEome9NUXDzDnT2LXHs7
|
||||||
a7mWFjJ15Ai5p9V6v5ZK30OKGETxrkokVir+oKmJPDx0iFiRNH7yJLnW3Oy/olLdyBKJUpD4TBG0pdhW
|
cno9LrW24l2FwvFVWNj7ABDirkKfUGgk8Ps6HT5oaUFjayvOnTmDfc3Nri6p9Id4mo560mRCKs0yFRUZ
|
||||||
VWWlzqn4FMS5/fvJFIz5amqIOSHhLtJYIOJ1JCaeG66tJaMoYAHWgweJDQscJ06QG2hXB8t2ZwqFqUgO
|
SXICX9LrkWtsxKWmJnSWlqIhNPQOALAAQEPP1q0XJsvLcVqnwxmdDo0nTqBJr8f506fxuk7n6mHZwTiB
|
||||||
FBlSKIrHKyutk6dOEQ5mpmCKw7qpPXvIxI4dpE2lcm2RSC4gtRSIefrFi19tUyqvt2/b5n+EpDEwDjcO
|
INprMpGcnDVXWGhcfO895FpbcamlBTmdDpe0WlyoqMBOqdR6RCi8DAA57q9Qbdv2SqdEcuPa0aOuh1ot
|
||||||
7IkbLXPu20euokiuUJj2E8MUjRkMtsnjxwMt4eCYQ3u5xkYyCXFzbq4nRSD4FMJGIAd0w3nRjESSiiLd
|
zmq1ONfYiPPNzWhra0PL8ePYx7KDSQJBzE8MkzlbUGBaPHXKXRKuqQm5hgbk6upwsaICDUlJ9ig+/zMA
|
||||||
li1biG3nTmJvaCCO3buJC8W8EOpuaPD3qNV37peXW7nDhwOOOcxxyOXq65+IpwkE56BXCzKC4pEgEPxc
|
UAOA2NNw8GOEwuhOiWRw5sgRNNXUoLm6Gufr69Gq1aJDr8f+6mrXkEx2+15enpE7edKdmNNqkaupQa6q
|
||||||
sTjtO4Wi64fqar+9ro44gdtkIh4I+FDMt2sXmYTbSSqMew73AXG0t0up9MqFQipOnaeD+eDpUQ0GXyUW
|
ygeP4fMvAEA5AMR64JS3rP5JISEx15KTBwwlJS6zRoMWjQZtlZVor6pCZ309OmtrcbGhARcJuL4eudra
|
||||||
p3dkZ3fbNm4kzq1biRt4jUbig8MJFJzABk6UlxPf6tXEp1YTD+jKy/PliETnsX47oM4F4DnxUPCXxcdn
|
f+Dl5TggkTjEAgGBk+QiAHj+sanqNZGGhIh6EhIGTYcOoaWsDG1lZehQq9FZUYELGg0ulJbiQl4eOvfu
|
||||||
dMjl3QMZGY89mzYRt0ZD3AxDXFIpcYlExBUdTVzz5pFuodDfnpTkZePi6IbWgUzwIphVPBSBdt2Sy/vH
|
RadMhnaZDAdSUpyJNH0JAI55kvNXg3vlvzM4OLZHLB4cE4mW7YcPo00uRxvDoDUsDK00jVY/P7TyeNgv
|
||||||
IWiHmAM4ARUOEBVF+rKz/zKkpn6L/HdBFpiTeCBsNTUmm1ptsQsEz4sDOjaQnPzYrNXeT0tMLMeSWDA3
|
ELi6IyIcbFAQaagGAOIA4IVnwb1yl+umWDw6R9No5vFwnsdDC4/nBrvHxo04kpDwZ0F09LcA8C4AxK8X
|
||||||
cZ/RuM9VUOCyw/1s4mPgIbBkZJA+ne7uW8uX52Dpf75WAuE2Gluca9e67TExz4k70XvaLio+CoYjI8kA
|
7paptLTSJJPNmPn8p+Eew7HIyGWDQnEvZuvWPAAIXDfcqVYft6anW800vSZ8lsfDBzwezsTG4ohSeeet
|
||||||
uJyT4++vqPjVwLK0TbMX8W7ffshRUuIJ59wpkZBHJSV/30hJ8VPxoaB4L+gCZoaZ7qf/ZLYiOIot9oIC
|
XbsSn1yMq8qmVust+/bZzAEBT8Etfn7uchH4NI+HkxSFYxSF3yQmukbz838tYFlSprVNHMeOtcxnZ9tX
|
||||||
r10oDAg/05YFC8hgaenvx1eu7Oldv37ckpZGfoHobXATXKMFKMuWTf9oMNwpkMvpC/Lpq95TW9tMxR3h
|
S24RCvFhdvZf16OiXAQ+4YEPUxQOUBQaGGZllHzJWiYOtVpvTk93mAUCN/ixsmzahOM5Ob+f2rNnaPjA
|
||||||
xBMSyOCqVX/UM0wHUhtKMjPfvltWdn8QvQ+Jd4J20EaLqFTTPRUVvZ9otXTj+SCC59mwweqIiwvvHOJ1
|
gbmZmBj8haLwFkVhP0XhdWJAxs6dKz8WFNxOF4vJBvnvVm8vL28m8PnV4KGhOJ6a+qiKYXoAoDo7Lu7t
|
||||||
CkU7Ek2AbqR4d37+G316/cidrKwn4pfBN+AS6E9Pf3xbr7+H3MWAz7PrdIMemSyscxPDfI+k+qB46EvF
|
O7m598ZjY33wXorCborCTmIila4M5ecPf6pQkMb7uxtvP3jQOB8U9DScJE9NfaRJTu4GgEoAII0MqU9L
|
||||||
31NYyPZVVIxcyMry/1v8q4gIchsFzBrNGPKKQDyvp7p687hG43ZDNOR8oLj4z53hxUPBb8zPz8PGDt/K
|
e31EpZq6HR/vg39HUfg1ReFVisJRkWj5lkp1FwC2uU3MSuW4PTx81eSVDPM9AFR54N6Tyl+bkcGO5OdP
|
||||||
ziYXg+LmvLzpzzWaR6VLl36MnJkCiPntlZWHrWVl3h6W9VPnjUplJ8ZnEw8F37hihYK24wusM6vV0xfg
|
XYqPd/0X/uWGDXhLJFo2yOWzAJAJAMEwVFJSPCeX22yhob7kY1lZf9SsDvfKvy4tLWVUqZy8mZCAVzxw
|
||||||
/CWBoBVzOjDTIkQEk5QU26vXf/agrMx5vrAQpy+yEeMMENJ5mjRL8C9VVb3zs043dlOrdZWkpNBvgR5I
|
Q0rKykW5/GHOjh2f+AzIxtRdWHjSmJvrGGBZF0leJ5H0PgPulb969+5kUo6LLOsyyGQrl+Xy2Rf5/HMA
|
||||||
AT2uT9bSH3FACdYFr3N9/F8A9GjSk7MevAbCPnDzAHVMP9b0Su/nEtQEff+/HIQWDBrj8f4B7zPYbtFn
|
oPSViLzMREQEDqtUn9/PzbVcysgYpiiqDgAYABCsAffK/2pR0Ts/K5Wz/QqFNTsqipwFKgAI80xX37vk
|
||||||
HR8AAAAASUVORK5CYII=
|
RxAASABgv+e63uX/HACQqUlmzgEAeHXVtQAAPE9icliTK/m/HpEQZP9/yTOIoS/Y32gy2FQGa9GfAAAA
|
||||||
|
AElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="MENU_DEL_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<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">
|
<data name="BTT_CLEAR_SELECTED.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_CLEAR_DONE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_CLEAR_DONE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
HR8AAAAASUVORK5CYII=
|
RxAASABgv+e63uX/HACQqUlmzgEAeHXVtQAAPE9icliTK/m/HpEQZP9/yTOIoS/Y32gy2FQGa9GfAAAA
|
||||||
|
AElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_CLEAR_ALL.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_CLEAR_ALL.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
HR8AAAAASUVORK5CYII=
|
RxAASABgv+e63uX/HACQqUlmzgEAeHXVtQAAPE9icliTK/m/HpEQZP9/yTOIoS/Y32gy2FQGa9GfAAAA
|
||||||
|
AElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="MENU_DEL_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<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">
|
<data name="MENU_DEL_CLEAR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
dCWdzmEAAAAASUVORK5CYII=
|
W/rDDwBEAHDYdd/q8n8BAOjUpDPnCAC8vuFaAACOKzE9rOmd/t+KaAi6/7/iuqihJ9jfOenaM1O34/0A
|
||||||
|
AAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="TOOLBAR_BOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<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">
|
<data name="BTT_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
hKygM1JCJAAAAABJRU5ErkJggg==
|
rwTiqI6ApvuidiViSNQekHhdhHhVL8AlQ/Cp10vnFTz/HxZurHotmkteAAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_ADD_PLS_ARR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_ADD_PLS_ARR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
H0WkrMjY2947AAAAAElFTkSuQmCC
|
II0aCGh8IOlXIoUk/QFJNyRIvxkFuGoK/uP10nkJz58BqISsoFjBRioAAAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MENU_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="MENU_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<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>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_STOP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_STOP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
bAAAAABJRU5ErkJggg==
|
CAIACQDs9lxXu/xfAAAyNcnM2QMAry+7FgCA9iQmhzW5kv+rEQlB9v9XPIMY+oL9DaXP2MIw0VMVAAAA
|
||||||
|
AElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_LOG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_LOG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFmSURBVFhH1dc/K4VhHMbxJ5EFEQbFiERKCotIrMJIiYEi
|
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGTSURBVFhH1ZfPK21RGIaf5GaCCAPF0JVISWEiElNhSIkB
|
||||||
pbwCZcOqJC9AikUWiqRkJYtSRDbESMT3V07dna7zHHru+9T51me+Ts//E+V7LRjFFAZRiZzUhDVc4/vX
|
RUr5C5QZpkryB0gxkQlFUjKlO1HKjcwQQyJatdXp7TtnH3t/Z+CpZ7be7z3tH2uvA7+cFmAUmAIGgSpd
|
||||||
B47Rh6D14Aqp4XQ36ECQ2nALNezaQjG8Vo5DqMF0bxiA1+bwCTWoLMFbNTiDGsrkABXw0jDsKldDmdyj
|
UCiagDXgCviMfAOOgT5d7E0P8C+jWL0GOjTkRRtwY5SqW0CJhtNSARwaZZYvwIAOSMsc8G6UZXNJB6Sh
|
||||||
HokrwCrUSBz7wXbRJs4eLkdQI9m0I3ENeIAaiGN3QjMSZ4fxv+ffnKIKibOnmhqI84V5eMleOHY41VAm
|
FjgzSnJ5AFTqoKQMR0+5luTyFmjQQUkoAlaNgjjDDw4PbWrC5nJkFORjuw5Lwl/gzhgeZ3gTmnVYEsJl
|
||||||
9k7wdgtW4wRqSHlCP7y2AjWmbMB7Y7DzqgZdz2iF9zrxCDXq2oU9uLz31+tgAcHahhp1DSFY9pGhRl29
|
/On9D54C1TosCWFX0+FxfgDzOigp4YMTLqeW5DJ8E9xewRrgxCjJ5gPQr0PSsmIUZXNDwx6MRfdVy9RH
|
||||||
CFYXxrMoQ7BmsZfFPkoRpHWow+56hX26BWkRatR1gRIEaQLvUMMpOyhCkBpxBzWcMoOgLUMNm0vUIWj2
|
oFXDHnQC90ahuhttXO7k+xwsaNCTbaNQHdKQJ+GQoYVqr4Y86QLGYyzXkCezwF6M+0CZBr1YNy65+hwd
|
||||||
ebaJF7jj5+hGTiqE/f+bxDRGUIt8LIp+AC/GHt3tQnwvAAAAAElFTkSuQmCC
|
3QrColGoXgClGvRiAng1SjPdAf5o0ItG4L9RmumMhrxZNkq/vQTqNeBNOJ5tAk9Sfg506+JCURz9/5sE
|
||||||
|
poERoE4X/Rq+AC/GHt09Rk0KAAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -39,6 +39,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
MyView = New FormView(Me)
|
MyView = New FormView(Me)
|
||||||
MyProgress = New MyProgress(TOOLBAR_BOTTOM, PR_MAIN, LBL_INFO)
|
MyProgress = New MyProgress(TOOLBAR_BOTTOM, PR_MAIN, LBL_INFO)
|
||||||
MyJob = New JobThread(Of MediaItem)
|
MyJob = New JobThread(Of MediaItem)
|
||||||
|
BTT_FILTER.Image = My.Resources.FilterPic
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Form handlers"
|
#Region "Form handlers"
|
||||||
@@ -57,6 +58,12 @@ Namespace DownloadObjects.STDownloader
|
|||||||
End If
|
End If
|
||||||
MyNotificator = New YTNotificator(Me)
|
MyNotificator = New YTNotificator(Me)
|
||||||
MyDownloaderSettings = MyYouTubeSettings
|
MyDownloaderSettings = MyYouTubeSettings
|
||||||
|
ProgramLogInitialize()
|
||||||
|
With ProgramLog
|
||||||
|
AddHandler .TextAdded, AddressOf ProgramLog_TextAdded
|
||||||
|
AddHandler .TextCleared, AddressOf ProgramLog_TextCleared
|
||||||
|
End With
|
||||||
|
UpdateLogButton()
|
||||||
End If
|
End If
|
||||||
|
|
||||||
With MyView : .Import() : .SetFormSize() : End With
|
With MyView : .Import() : .SetFormSize() : End With
|
||||||
@@ -89,15 +96,18 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Dim b As Boolean = True
|
Dim b As Boolean = True
|
||||||
Select Case e.KeyCode
|
Select Case e.KeyCode
|
||||||
Case Keys.Insert : BTT_ADD.PerformClick()
|
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
|
Case Else : b = False
|
||||||
End Select
|
End Select
|
||||||
If b Then e.Handled = True
|
If b Then e.Handled = True
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Refill, save list"
|
#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()
|
Dim c As List(Of IYouTubeMediaContainer) = LoadData_GetFiles()
|
||||||
|
If c.ListExists Then MyYouTubeSettings.FILTER.RemoveAll(c)
|
||||||
If c.ListExists Then
|
If c.ListExists Then
|
||||||
c.Sort(New ContainerDateComparer)
|
c.Sort(New ContainerDateComparer)
|
||||||
SuspendLayout()
|
SuspendLayout()
|
||||||
@@ -126,7 +136,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "Controls"
|
#Region "Controls"
|
||||||
Protected Sub ControlCreateAndAdd(ByVal Container As IYouTubeMediaContainer, Optional ByVal DisableDownload As Boolean = False,
|
Protected Sub ControlCreateAndAdd(ByVal Container As IYouTubeMediaContainer, Optional ByVal DisableDownload As Boolean = False,
|
||||||
Optional ByVal PerformClick As Boolean = True, Optional ByVal IsLoading As Boolean = False)
|
Optional ByVal PerformClick As Boolean = True, Optional ByVal IsLoading As Boolean = False,
|
||||||
|
Optional ByVal UseCookies As Boolean = False)
|
||||||
ControlInvokeFast(TP_CONTROLS, Sub()
|
ControlInvokeFast(TP_CONTROLS, Sub()
|
||||||
With TP_CONTROLS
|
With TP_CONTROLS
|
||||||
.SuspendLayout()
|
.SuspendLayout()
|
||||||
@@ -136,7 +147,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
.RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 60))
|
.RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 60))
|
||||||
.RowCount = .RowStyles.Count
|
.RowCount = .RowStyles.Count
|
||||||
OffsetControls(0, True)
|
OffsetControls(0, True)
|
||||||
Dim cnt As New MediaItem(Container) With {.Dock = DockStyle.Fill, .Margin = New Padding(0)}
|
Dim cnt As New MediaItem(Container) With {.Dock = DockStyle.Fill, .Margin = New Padding(0), .UseCookies = UseCookies}
|
||||||
AddHandler cnt.FileDownloaded, AddressOf MediaControl_FileDownloaded
|
AddHandler cnt.FileDownloaded, AddressOf MediaControl_FileDownloaded
|
||||||
AddHandler cnt.Removal, AddressOf MediaControl_Removal
|
AddHandler cnt.Removal, AddressOf MediaControl_Removal
|
||||||
AddHandler cnt.DownloadAgain, AddressOf MediaControl_DownloadAgain
|
AddHandler cnt.DownloadAgain, AddressOf MediaControl_DownloadAgain
|
||||||
@@ -157,7 +168,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If PerformClick Then cnt.PerformClick()
|
If PerformClick Then cnt.PerformClick()
|
||||||
If Not DisableDownload And MyDownloaderSettings.DownloadAutomatically Then AddToDownload(cnt, True)
|
If Not DisableDownload And MyDownloaderSettings.DownloadAutomatically Then AddToDownload(cnt, True)
|
||||||
End With
|
End With
|
||||||
End Sub, EDP.None)
|
End Sub, EDP.SendToLog)
|
||||||
End Sub
|
End Sub
|
||||||
#Region "Controls rendering"
|
#Region "Controls rendering"
|
||||||
Private Overloads Sub OffsetControls()
|
Private Overloads Sub OffsetControls()
|
||||||
@@ -247,7 +258,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Dim useCookiesParse As Boolean? = Nothing
|
Dim useCookiesParse As Boolean? = Nothing
|
||||||
If useCookies Then useCookiesParse = True
|
If useCookies Then useCookiesParse = True
|
||||||
Dim standardizeUrls As Boolean = MyYouTubeSettings.StandardizeURLs
|
Dim standardizeUrls As Boolean = MyYouTubeSettings.StandardizeURLs
|
||||||
Dim standardize As Func(Of String, String) = Function(input) If(standardizeUrls, YouTubeFunctions.StandardizeURL(input), input)
|
Dim standardize As Func(Of String, String) = Function(input) If(standardizeUrls, YouTubeFunctions.StandardizeURL(input), input.StringTrim)
|
||||||
|
|
||||||
Dim c As IYouTubeMediaContainer = Nothing
|
Dim c As IYouTubeMediaContainer = Nothing
|
||||||
Dim url$ = String.Empty
|
Dim url$ = String.Empty
|
||||||
@@ -325,21 +336,22 @@ Namespace DownloadObjects.STDownloader
|
|||||||
pForm.Dispose()
|
pForm.Dispose()
|
||||||
End If
|
End If
|
||||||
If Not c Is Nothing Then
|
If Not c Is Nothing Then
|
||||||
|
If Not c.HasElements Then DirectCast(c, YouTubeMediaContainerBase).FileForceArtist()
|
||||||
Dim f As Form
|
Dim f As Form
|
||||||
Select Case c.ObjectType
|
Select Case c.ObjectType
|
||||||
Case YouTubeMediaType.Single : f = New VideoOptionsForm(c)
|
Case YouTubeMediaType.Single : f = New VideoOptionsForm(c) With {.UseCookies = useCookies}
|
||||||
Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList
|
Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList
|
||||||
If c.IsMusic Then
|
If c.IsMusic Then
|
||||||
f = New MusicPlaylistsForm(c)
|
f = New MusicPlaylistsForm(c)
|
||||||
Else
|
Else
|
||||||
f = New VideoOptionsForm(c)
|
f = New VideoOptionsForm(c) With {.UseCookies = useCookies}
|
||||||
End If
|
End If
|
||||||
Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType")
|
Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType")
|
||||||
End Select
|
End Select
|
||||||
If Not f Is Nothing Then
|
If Not f Is Nothing Then
|
||||||
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
|
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
|
||||||
f.ShowDialog()
|
f.ShowDialog()
|
||||||
If f.DialogResult = DialogResult.OK AndAlso ValidateContainerURL(c) Then ControlCreateAndAdd(c, disableDown)
|
If f.DialogResult = DialogResult.OK AndAlso ValidateContainerURL(c) Then ControlCreateAndAdd(c, disableDown,,, useCookies)
|
||||||
f.Dispose()
|
f.Dispose()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -408,6 +420,12 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[VideoListForm.ValidateContainerURL]", True)
|
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[VideoListForm.ValidateContainerURL]", True)
|
||||||
End Try
|
End Try
|
||||||
End Function
|
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
|
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
||||||
With TP_CONTROLS
|
With TP_CONTROLS
|
||||||
If .Controls.Count > 0 Then
|
If .Controls.Count > 0 Then
|
||||||
@@ -449,12 +467,26 @@ Namespace DownloadObjects.STDownloader
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
|
#Region "LOG"
|
||||||
Private Sub BTT_LOG_Click(sender As Object, e As EventArgs) Handles BTT_LOG.Click
|
Private Sub BTT_LOG_Click(sender As Object, e As EventArgs) Handles BTT_LOG.Click
|
||||||
MyMainLOG_ShowForm(DesignXML,,,, AddressOf UpdateLogButton)
|
MyMainLOG_ShowForm(DesignXML,,,, AddressOf UpdateLogButton)
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub UpdateLogButton()
|
Private Sub UpdateLogButton()
|
||||||
If AppMode Then MyMainLOG_UpdateLogButton(BTT_LOG, TOOLBAR_TOP)
|
If AppMode Then
|
||||||
|
Try : MyMainLOG_UpdateLogButton(BTT_LOG, TOOLBAR_TOP) : Catch : End Try
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
Private _LogUpdateButtonSuspended As Boolean = False
|
||||||
|
Private Sub ProgramLog_TextAdded(ByVal Sender As Object, ByVal e As EventArgs)
|
||||||
|
If Not _LogUpdateButtonSuspended Then
|
||||||
|
_LogUpdateButtonSuspended = True
|
||||||
|
Try : ControlInvokeFast(TOOLBAR_TOP, BTT_LOG, AddressOf UpdateLogButton, EDP.None) : Catch : End Try
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub ProgramLog_TextCleared(ByVal Sender As Object, ByVal e As EventArgs)
|
||||||
|
_LogUpdateButtonSuspended = False
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
Private Sub BTT_BUG_REPORT_Click(sender As Object, e As EventArgs) Handles BTT_BUG_REPORT.Click
|
Private Sub BTT_BUG_REPORT_Click(sender As Object, e As EventArgs) Handles BTT_BUG_REPORT.Click
|
||||||
Try
|
Try
|
||||||
With MyYouTubeSettings
|
With MyYouTubeSettings
|
||||||
@@ -473,7 +505,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Protected Sub CheckVersionImpl(ByVal Force As Boolean)
|
Protected Sub CheckVersionImpl(ByVal Force As Boolean)
|
||||||
CheckVersion(Force)
|
CheckVersion(Force)
|
||||||
End Sub
|
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()
|
ControlInvokeFast(TP_CONTROLS, Sub()
|
||||||
With TP_CONTROLS
|
With TP_CONTROLS
|
||||||
If .Controls.Count > 0 Then
|
If .Controls.Count > 0 Then
|
||||||
@@ -488,7 +521,10 @@ Namespace DownloadObjects.STDownloader
|
|||||||
For i = rCnt.Count - 1 To 0 Step -1
|
For i = rCnt.Count - 1 To 0 Step -1
|
||||||
cnt = .Controls(rCnt(i))
|
cnt = .Controls(rCnt(i))
|
||||||
.Controls.RemoveAt(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()
|
cnt.Dispose()
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
|
|||||||
261
SCrawler.YouTube/Editors/BugReporterForm.Designer.vb
generated
@@ -24,7 +24,6 @@ Namespace Editors
|
|||||||
Private Sub InitializeComponent()
|
Private Sub InitializeComponent()
|
||||||
Me.components = New System.ComponentModel.Container()
|
Me.components = New System.ComponentModel.Container()
|
||||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
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 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 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()
|
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 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 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 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 ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||||
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
Dim 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_DESCR = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_URL_PROFILE = 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_URL_POST = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_REPRODUCE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_REPRODUCE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_EXPECT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_EXPECT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_LOG = 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.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_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TP_MAIN.SuspendLayout()
|
TP_MAIN.SuspendLayout()
|
||||||
TP_BUTTONS.SuspendLayout()
|
|
||||||
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
CType(Me.TXT_URL_PROFILE, 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_URL_POST, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
CType(Me.TXT_REPRODUCE, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_REPRODUCE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
CType(Me.TXT_EXPECT, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_EXPECT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
CType(Me.TXT_LOG, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_LOG, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
|
TP_BUTTONS.SuspendLayout()
|
||||||
CType(Me.TXT_FILES, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_FILES, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
Me.SuspendLayout()
|
Me.SuspendLayout()
|
||||||
'
|
'
|
||||||
@@ -88,6 +88,123 @@ Namespace Editors
|
|||||||
TP_MAIN.Size = New System.Drawing.Size(584, 461)
|
TP_MAIN.Size = New System.Drawing.Size(584, 461)
|
||||||
TP_MAIN.TabIndex = 0
|
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
|
||||||
'
|
'
|
||||||
TP_BUTTONS.ColumnCount = 6
|
TP_BUTTONS.ColumnCount = 6
|
||||||
@@ -119,7 +236,7 @@ Namespace Editors
|
|||||||
Me.BTT_EMAIL.Name = "BTT_EMAIL"
|
Me.BTT_EMAIL.Name = "BTT_EMAIL"
|
||||||
Me.BTT_EMAIL.Size = New System.Drawing.Size(94, 24)
|
Me.BTT_EMAIL.Size = New System.Drawing.Size(94, 24)
|
||||||
Me.BTT_EMAIL.TabIndex = 1
|
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.TT_MAIN.SetToolTip(Me.BTT_EMAIL, "Create a message to send via email.")
|
||||||
Me.BTT_EMAIL.UseVisualStyleBackColor = True
|
Me.BTT_EMAIL.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
@@ -167,129 +284,6 @@ Namespace Editors
|
|||||||
Me.TT_MAIN.SetToolTip(Me.BTT_ANON, resources.GetString("BTT_ANON.ToolTip"))
|
Me.TT_MAIN.SetToolTip(Me.BTT_ANON, resources.GetString("BTT_ANON.ToolTip"))
|
||||||
Me.BTT_ANON.UseVisualStyleBackColor = True
|
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
|
'TXT_FILES
|
||||||
'
|
'
|
||||||
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
|
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.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.TXT_FILES.GroupBoxed = True
|
Me.TXT_FILES.GroupBoxed = True
|
||||||
Me.TXT_FILES.GroupBoxText = "Files"
|
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.Location = New System.Drawing.Point(3, 359)
|
||||||
Me.TXT_FILES.Multiline = True
|
Me.TXT_FILES.Multiline = True
|
||||||
Me.TXT_FILES.Name = "TXT_FILES"
|
Me.TXT_FILES.Name = "TXT_FILES"
|
||||||
@@ -332,13 +325,13 @@ Namespace Editors
|
|||||||
Me.Name = "BugReporterForm"
|
Me.Name = "BugReporterForm"
|
||||||
Me.Text = "New message"
|
Me.Text = "New message"
|
||||||
TP_MAIN.ResumeLayout(False)
|
TP_MAIN.ResumeLayout(False)
|
||||||
TP_BUTTONS.ResumeLayout(False)
|
|
||||||
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
CType(Me.TXT_URL_PROFILE, 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_URL_POST, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
CType(Me.TXT_REPRODUCE, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_REPRODUCE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
CType(Me.TXT_EXPECT, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_EXPECT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
CType(Me.TXT_LOG, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_LOG, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
|
TP_BUTTONS.ResumeLayout(False)
|
||||||
CType(Me.TXT_FILES, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_FILES, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
Me.ResumeLayout(False)
|
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">
|
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton3.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>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton4.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>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
wwAADsMBx2+oZAAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
khP7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
@@ -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">
|
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -10,6 +10,7 @@ Imports System.Threading
|
|||||||
Imports PersonalUtilities.Tools
|
Imports PersonalUtilities.Tools
|
||||||
Imports PersonalUtilities.Tools.Web
|
Imports PersonalUtilities.Tools.Web
|
||||||
Imports PersonalUtilities.Functions.Messaging
|
Imports PersonalUtilities.Functions.Messaging
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Imports SCrawler.DownloadObjects.STDownloader
|
Imports SCrawler.DownloadObjects.STDownloader
|
||||||
Public Module MainModShared
|
Public Module MainModShared
|
||||||
Public Property BATCH As BatchExecutor
|
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
|
Public Shared Function GetProgramEnvirText(ByVal EnvirData As IDownloaderSettings, ByVal IsYouTube As Boolean) As String
|
||||||
Try
|
Try
|
||||||
Dim output$ = String.Empty
|
Dim output$ = String.Empty
|
||||||
|
Dim verAfter As RParams = RParams.DM("\A\w\:\\.*", 0, EDP.ReturnValue)
|
||||||
Using b As New BatchExecutor(True)
|
Using b As New BatchExecutor(True)
|
||||||
Dim f As SFile
|
Dim f As SFile
|
||||||
Dim cmd$, ff$, vText$
|
Dim cmd$, ff$, vText$
|
||||||
|
Dim ii%
|
||||||
|
|
||||||
For i% = 0 To IIf(IsYouTube, 1, 3)
|
For i% = 0 To IIf(IsYouTube, 1, 3)
|
||||||
cmd = "--version"
|
cmd = "--version"
|
||||||
@@ -154,7 +157,17 @@ Namespace Editors
|
|||||||
Else
|
Else
|
||||||
b.Reset()
|
b.Reset()
|
||||||
b.Execute($"""{f}"" {cmd}", EDP.None)
|
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}")
|
output.StringAppendLine($"{ff} version: {vText}")
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
|
|||||||
<Assembly: AssemblyDescription("YouTube plugin environment")>
|
<Assembly: AssemblyDescription("YouTube plugin environment")>
|
||||||
<Assembly: AssemblyCompany("AndyProgram")>
|
<Assembly: AssemblyCompany("AndyProgram")>
|
||||||
<Assembly: AssemblyProduct("SCrawler.YouTube")>
|
<Assembly: AssemblyProduct("SCrawler.YouTube")>
|
||||||
<Assembly: AssemblyCopyright("Copyright © 2024")>
|
<Assembly: AssemblyCopyright("Copyright © 2026")>
|
||||||
<Assembly: AssemblyTrademark("AndyProgram")>
|
<Assembly: AssemblyTrademark("AndyProgram")>
|
||||||
|
|
||||||
<Assembly: ComVisible(False)>
|
<Assembly: ComVisible(False)>
|
||||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2024.5.4.0")>
|
<Assembly: AssemblyVersion("2025.11.25.0")>
|
||||||
<Assembly: AssemblyFileVersion("2024.5.4.0")>
|
<Assembly: AssemblyFileVersion("2025.11.25.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ Namespace API.YouTube.Objects
|
|||||||
_File = CleanFileName(_File)
|
_File = CleanFileName(_File)
|
||||||
End If
|
End If
|
||||||
End Sub
|
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
|
Public Overrides Function ToString(ByVal ForMediaItem As Boolean) As String
|
||||||
Dim s$ = SizeStr
|
Dim s$ = SizeStr
|
||||||
If Not s.IsEmptyString Then s = $" [{s}]"
|
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 IsShorts As Boolean = False Implements IYouTubeMediaContainer.IsShorts
|
||||||
<XMLEC> Public Property ID As String Implements IYouTubeMediaContainer.ID, IUserMedia.PostID
|
<XMLEC> Public Property ID As String Implements IYouTubeMediaContainer.ID, IUserMedia.PostID
|
||||||
<XMLEC> Public Property Title As String Implements IDownloadableMedia.Title
|
<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 PlaylistID As String Implements IYouTubeMediaContainer.PlaylistID
|
||||||
<XMLEC> Public Property PlaylistTitle As String Implements IYouTubeMediaContainer.PlaylistTitle
|
<XMLEC> Public Property PlaylistTitle As String Implements IYouTubeMediaContainer.PlaylistTitle
|
||||||
<XMLEC> Public Property UserID As String Implements IYouTubeMediaContainer.UserID
|
<XMLEC> Public Property UserID As String Implements IYouTubeMediaContainer.UserID
|
||||||
@@ -175,7 +177,9 @@ Namespace API.YouTube.Objects
|
|||||||
Protected _ThumbnailUrl As String = String.Empty
|
Protected _ThumbnailUrl As String = String.Empty
|
||||||
<XMLEC> Public Overridable Property ThumbnailUrl As String Implements IDownloadableMedia.ThumbnailUrl
|
<XMLEC> Public Overridable Property ThumbnailUrl As String Implements IDownloadableMedia.ThumbnailUrl
|
||||||
Get
|
Get
|
||||||
If _ThumbnailUrl.IsEmptyString And Thumbnails.Count > 0 Then
|
If Not CoverURL.IsEmptyString Then
|
||||||
|
Return CoverURL
|
||||||
|
ElseIf _ThumbnailUrl.IsEmptyString And Thumbnails.Count > 0 Then
|
||||||
Return Thumbnails.FirstOrDefault.URL
|
Return Thumbnails.FirstOrDefault.URL
|
||||||
Else
|
Else
|
||||||
Return _ThumbnailUrl
|
Return _ThumbnailUrl
|
||||||
@@ -267,12 +271,11 @@ Namespace API.YouTube.Objects
|
|||||||
<XMLEC(CollectionMode:=CollectionModes.String)>
|
<XMLEC(CollectionMode:=CollectionModes.String)>
|
||||||
Friend ReadOnly Property PostProcessing_OutputAudioFormats As List(Of String)
|
Friend ReadOnly Property PostProcessing_OutputAudioFormats As List(Of String)
|
||||||
Friend Sub PostProcessing_OutputAudioFormats_Reset()
|
Friend Sub PostProcessing_OutputAudioFormats_Reset()
|
||||||
PostProcessing_OutputAudioFormats.Clear()
|
With PostProcessing_OutputAudioFormats
|
||||||
PostProcessing_OutputAudioFormats.ListAddList(MyYouTubeSettings.DefaultAudioCodecAddit)
|
.Clear()
|
||||||
If PostProcessing_OutputAudioFormats.Count > 0 Then
|
.ListAddList(MyYouTubeSettings.DefaultAudioCodecAddit)
|
||||||
PostProcessing_OutputAudioFormats.Sort()
|
If .Count > 0 Then .Sort()
|
||||||
PostProcessing_OutputAudioFormats.RemoveAll(Function(s) s = -1)
|
End With
|
||||||
End If
|
|
||||||
End Sub
|
End Sub
|
||||||
<XMLEC("OutputAudioBitrate")> Protected _OutputAudioBitrate As Integer = -1
|
<XMLEC("OutputAudioBitrate")> Protected _OutputAudioBitrate As Integer = -1
|
||||||
Friend Property OutputAudioBitrate As Integer
|
Friend Property OutputAudioBitrate As Integer
|
||||||
@@ -322,21 +325,19 @@ Namespace API.YouTube.Objects
|
|||||||
<XMLEC(CollectionMode:=CollectionModes.String)>
|
<XMLEC(CollectionMode:=CollectionModes.String)>
|
||||||
Friend ReadOnly Property PostProcessing_OutputSubtitlesFormats As List(Of String)
|
Friend ReadOnly Property PostProcessing_OutputSubtitlesFormats As List(Of String)
|
||||||
Friend Sub PostProcessing_OutputSubtitlesFormats_Reset()
|
Friend Sub PostProcessing_OutputSubtitlesFormats_Reset()
|
||||||
PostProcessing_OutputSubtitlesFormats.Clear()
|
With PostProcessing_OutputSubtitlesFormats
|
||||||
PostProcessing_OutputSubtitlesFormats.ListAddList(MyYouTubeSettings.DefaultSubtitlesFormatAddit)
|
.Clear()
|
||||||
If PostProcessing_OutputSubtitlesFormats.Count > 0 Then
|
.ListAddList(MyYouTubeSettings.DefaultSubtitlesFormatAddit)
|
||||||
PostProcessing_OutputSubtitlesFormats.Sort()
|
If .Count > 0 Then .Sort()
|
||||||
PostProcessing_OutputSubtitlesFormats.RemoveAll(Function(s) s = -1)
|
End With
|
||||||
End If
|
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub SubtitlesSelectedIndexesReset()
|
Friend Sub SubtitlesSelectedIndexesReset()
|
||||||
SubtitlesSelectedIndexes.Clear()
|
With SubtitlesSelectedIndexes
|
||||||
|
.Clear()
|
||||||
Dim subs As List(Of Subtitles) = Subtitles
|
Dim subs As List(Of Subtitles) = Subtitles
|
||||||
SubtitlesSelectedIndexes.ListAddList(MyYouTubeSettings.DefaultSubtitles.Select(Function(s) subs.FindIndex(Function(ss) ss.ID = s)))
|
.ListAddList(MyYouTubeSettings.DefaultSubtitles.Select(Function(s) subs.FindIndex(Function(ss) ss.ID = s)))
|
||||||
If SubtitlesSelectedIndexes.Count > 0 Then
|
If .Count > 0 Then .Sort() : .RemoveAll(Function(s) s = -1)
|
||||||
SubtitlesSelectedIndexes.Sort()
|
End With
|
||||||
SubtitlesSelectedIndexes.RemoveAll(Function(s) s = -1)
|
|
||||||
End If
|
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub SetElementsSubtitles(ByVal Source As YouTubeMediaContainerBase)
|
Private Sub SetElementsSubtitles(ByVal Source As YouTubeMediaContainerBase)
|
||||||
If Not Source Is Nothing And HasElements Then
|
If Not Source Is Nothing And HasElements Then
|
||||||
@@ -355,6 +356,14 @@ Namespace API.YouTube.Objects
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#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"
|
#Region "IUserMedia Support"
|
||||||
<XMLEC> Private Property Attempts As Integer Implements IUserMedia.Attempts
|
<XMLEC> Private Property Attempts As Integer Implements IUserMedia.Attempts
|
||||||
Private _Object As Object = Nothing
|
Private _Object As Object = Nothing
|
||||||
@@ -442,6 +451,19 @@ Namespace API.YouTube.Objects
|
|||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
<XMLEC> Public Property Height As Integer Implements IYouTubeMediaContainer.Height
|
<XMLEC> Public Property Height As Integer Implements IYouTubeMediaContainer.Height
|
||||||
|
Friend ReadOnly Property HeightBase As Integer
|
||||||
|
Get
|
||||||
|
If Height > 0 Then
|
||||||
|
Return Height
|
||||||
|
ElseIf SelectedVideoIndex.ValueBetween(0, MediaObjects.Count - 1) Then
|
||||||
|
Return SelectedVideo.Height
|
||||||
|
ElseIf SelectedAudioIndex.ValueBetween(0, MediaObjects.Count - 1) Then
|
||||||
|
Return SelectedAudio.Height
|
||||||
|
Else
|
||||||
|
Return 0
|
||||||
|
End If
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Protected _Bitrate As Integer = 0
|
Protected _Bitrate As Integer = 0
|
||||||
<XMLEC> Public Overridable Property Bitrate As Integer Implements IYouTubeMediaContainer.Bitrate
|
<XMLEC> Public Overridable Property Bitrate As Integer Implements IYouTubeMediaContainer.Bitrate
|
||||||
Get
|
Get
|
||||||
@@ -459,6 +481,20 @@ Namespace API.YouTube.Objects
|
|||||||
Me._Bitrate = _Bitrate
|
Me._Bitrate = _Bitrate
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Friend ReadOnly Property BitrateBase As Integer
|
||||||
|
Get
|
||||||
|
If Bitrate > 0 Then
|
||||||
|
Return Bitrate
|
||||||
|
ElseIf OutputAudioBitrate > 0 Then
|
||||||
|
Return OutputAudioBitrate
|
||||||
|
ElseIf HasElements Then
|
||||||
|
Try : Return Elements.Average(Function(e) DirectCast(e, YouTubeMediaContainerBase).BitrateBase) : Catch : End Try
|
||||||
|
ElseIf SelectedAudioIndex.ValueBetween(0, MediaObjects.Count - 1) Then
|
||||||
|
Return SelectedAudio.Bitrate
|
||||||
|
End If
|
||||||
|
Return 0
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
<XMLEC> Public Property DateCreated As Date = Now Implements IYouTubeMediaContainer.DateCreated
|
<XMLEC> Public Property DateCreated As Date = Now Implements IYouTubeMediaContainer.DateCreated
|
||||||
<XMLEC> Public Property DateAdded As Date Implements IYouTubeMediaContainer.DateAdded
|
<XMLEC> Public Property DateAdded As Date Implements IYouTubeMediaContainer.DateAdded
|
||||||
Private Property IUserMedia_PostDate As Date? Implements IUserMedia.PostDate
|
Private Property IUserMedia_PostDate As Date? Implements IUserMedia.PostDate
|
||||||
@@ -656,6 +692,24 @@ Namespace API.YouTube.Objects
|
|||||||
End If
|
End If
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Protected Friend Overridable Sub FileForceArtist()
|
||||||
|
End Sub
|
||||||
|
Friend Sub FileDateUpdate()
|
||||||
|
Dim n$ = _File.Name.StringTrim
|
||||||
|
Dim s$ = IIf(n.IsEmptyString, String.Empty, " ")
|
||||||
|
Dim c$ = AccountName.IfNullOrEmpty(UserID)
|
||||||
|
Select Case MyYouTubeSettings.FileAddDateToFileName.Value
|
||||||
|
Case FileDateMode.Before : n = $"[{DateAdded:yyyy-MM-dd}]{s}{n}"
|
||||||
|
Case FileDateMode.After : n = $"{n}{s}[{DateAdded:yyyy-MM-dd}]"
|
||||||
|
End Select
|
||||||
|
If Not c.IsEmptyString Then
|
||||||
|
Select Case MyYouTubeSettings.FileAddChannelToFileName.Value
|
||||||
|
Case FileDateMode.Before : n = $"[{c}] {n}"
|
||||||
|
Case FileDateMode.After : n = $"{n} [{c}]"
|
||||||
|
End Select
|
||||||
|
End If
|
||||||
|
_File.Name = n
|
||||||
|
End Sub
|
||||||
Public Property FileSettings As SFile
|
Public Property FileSettings As SFile
|
||||||
Private Property IUserMedia_File As String Implements IUserMedia.File
|
Private Property IUserMedia_File As String Implements IUserMedia.File
|
||||||
Get
|
Get
|
||||||
@@ -694,6 +748,7 @@ Namespace API.YouTube.Objects
|
|||||||
#Region "Command"
|
#Region "Command"
|
||||||
<XMLEC> Public Property UseCookies As Boolean = MyYouTubeSettings.DefaultUseCookies Implements IYouTubeMediaContainer.UseCookies
|
<XMLEC> Public Property UseCookies As Boolean = MyYouTubeSettings.DefaultUseCookies Implements IYouTubeMediaContainer.UseCookies
|
||||||
Protected Const mp3 As String = "mp3"
|
Protected Const mp3 As String = "mp3"
|
||||||
|
Private Const mp4 As String = "mp4"
|
||||||
Private Const aac As String = "aac"
|
Private Const aac As String = "aac"
|
||||||
Private Const ac3 As String = "ac3"
|
Private Const ac3 As String = "ac3"
|
||||||
Protected PostProcessing_AudioAC3 As Boolean = False
|
Protected PostProcessing_AudioAC3 As Boolean = False
|
||||||
@@ -729,7 +784,12 @@ Namespace API.YouTube.Objects
|
|||||||
'2023.3.4 -> 2023.7.6
|
'2023.3.4 -> 2023.7.6
|
||||||
'cmd.StringAppend($"ba*[format_id={SelectedAudio.ID}]", "+")
|
'cmd.StringAppend($"ba*[format_id={SelectedAudio.ID}]", "+")
|
||||||
cmd.StringAppend(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
|
PostProcessing_AudioAC3 = True
|
||||||
formats.StringAppend($"--audio-format {aac}", " ")
|
formats.StringAppend($"--audio-format {aac}", " ")
|
||||||
atCodec = aac
|
atCodec = aac
|
||||||
@@ -767,15 +827,20 @@ Namespace API.YouTube.Objects
|
|||||||
subs = ListAddList(Nothing, Subtitles.Select(Function(s, i) If(SubtitlesSelectedIndexes.Contains(i), s.FullID, String.Empty)),
|
subs = ListAddList(Nothing, Subtitles.Select(Function(s, i) If(SubtitlesSelectedIndexes.Contains(i), s.FullID, String.Empty)),
|
||||||
LAP.NotContainsOnly, EDP.ReturnValue).ListToString(",")
|
LAP.NotContainsOnly, EDP.ReturnValue).ListToString(",")
|
||||||
subs = $"--write-subs --write-auto-subs --sub-format {OutputSubtitlesFormat.StringToLower} --sub-langs ""{subs}"" --convert-subs {OutputSubtitlesFormat.StringToLower}"
|
subs = $"--write-subs --write-auto-subs --sub-format {OutputSubtitlesFormat.StringToLower} --sub-langs ""{subs}"" --convert-subs {OutputSubtitlesFormat.StringToLower}"
|
||||||
|
If MyYouTubeSettings.DefaultSubtitlesEmbed Then subs = $"--write-auto-sub --embed-subs {subs}"
|
||||||
End If
|
End If
|
||||||
If Not cmd.IsEmptyString Then
|
If Not cmd.IsEmptyString Then
|
||||||
'2023.3.4 -> 2023.7.6
|
'2023.3.4 -> 2023.7.6
|
||||||
'cmd = $"yt-dlp -f ""{cmd}"""
|
'cmd = $"yt-dlp -f ""{cmd}"""
|
||||||
'cmd = $"yt-dlp -f {cmd}"
|
'cmd = $"yt-dlp -f {cmd}"
|
||||||
cmd = $"{YTDLP_NAME} -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(formats, " ")
|
||||||
cmd.StringAppend(subs, " ")
|
cmd.StringAppend(subs, " ")
|
||||||
|
If MyYouTubeSettings.ErrorsIgnore Then cmd &= " --no-abort-on-error --ignore-errors"
|
||||||
cmd.StringAppend(YouTubeFunctions.GetCookiesCommand(WithCookies, YouTubeCookieNetscapeFile), " ")
|
cmd.StringAppend(YouTubeFunctions.GetCookiesCommand(WithCookies, YouTubeCookieNetscapeFile), " ")
|
||||||
cmd &= $" {URL} -o ""{File.PathWithSeparator}{File.Name}"""
|
cmd &= $" {URL} -o ""{File.PathWithSeparator}{File.Name}"""
|
||||||
File.Exists(SFO.Path, True)
|
File.Exists(SFO.Path, True)
|
||||||
@@ -793,6 +858,8 @@ Namespace API.YouTube.Objects
|
|||||||
_Subtitles = New List(Of Subtitles)
|
_Subtitles = New List(Of Subtitles)
|
||||||
_SubtitlesDelegated = New List(Of Subtitles)
|
_SubtitlesDelegated = New List(Of Subtitles)
|
||||||
SubtitlesSelectedIndexes = New List(Of Integer)
|
SubtitlesSelectedIndexes = New List(Of Integer)
|
||||||
|
Chapters = New List(Of TrimOption)
|
||||||
|
TrimOptions = New List(Of TrimOption)
|
||||||
MediaObjects = New List(Of MediaObject)
|
MediaObjects = New List(Of MediaObject)
|
||||||
_Files = New List(Of SFile)
|
_Files = New List(Of SFile)
|
||||||
|
|
||||||
@@ -866,10 +933,14 @@ Namespace API.YouTube.Objects
|
|||||||
Return Nothing
|
Return Nothing
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
Private Function GetPlaylistRow(ByVal Element As YouTubeMediaContainerBase, Optional ByVal __file As SFile = Nothing) As String
|
Private Function GetPlaylistRow(ByVal Element As YouTubeMediaContainerBase, Optional ByVal __file As SFile = Nothing,
|
||||||
|
Optional ByVal Mode As M3U8CreationMode = M3U8CreationMode.Absolute) As String
|
||||||
Const m3u8DataRow$ = "#EXTINF:{0},{1}" & vbCrLf & "{2}"
|
Const m3u8DataRow$ = "#EXTINF:{0},{1}" & vbCrLf & "{2}"
|
||||||
With Element
|
With Element
|
||||||
Dim f As SFile = __file.IfNullOrEmpty(.File)
|
Dim f As SFile = __file.IfNullOrEmpty(.File)
|
||||||
|
Dim fStr$ = f.ToString.StringReplaceSymbols({"\"}, "/", EDP.ReturnValue)
|
||||||
|
Dim __f$ = SymbolsConverter.ASCII.Extended.EncodeSymbolsOnly(If(Mode = M3U8CreationMode.Absolute, fStr, f.File), M3U8ExcludedSymbols)
|
||||||
|
If Mode = M3U8CreationMode.Absolute Then __f = $"file:///{__f}"
|
||||||
Dim fName$ = .Title.IfNullOrEmpty(f.Name)
|
Dim fName$ = .Title.IfNullOrEmpty(f.Name)
|
||||||
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendNumber And .PlaylistIndex > 0 Then fName = $"{ .PlaylistIndex}. {fName}"
|
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendNumber And .PlaylistIndex > 0 Then fName = $"{ .PlaylistIndex}. {fName}"
|
||||||
If Not .UserTitle.IsEmptyString Then
|
If Not .UserTitle.IsEmptyString Then
|
||||||
@@ -877,10 +948,7 @@ Namespace API.YouTube.Objects
|
|||||||
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendArtist Then fName = $"{ .UserTitle} - {fName}"
|
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendArtist Then fName = $"{ .UserTitle} - {fName}"
|
||||||
End If
|
End If
|
||||||
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendExt Then fName &= $".{f.Extension}"
|
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendExt Then fName &= $".{f.Extension}"
|
||||||
Return String.Format(m3u8DataRow,
|
Return String.Format(m3u8DataRow, CInt(.Duration.TotalSeconds), fName, __f)
|
||||||
CInt(.Duration.TotalSeconds),
|
|
||||||
fName,
|
|
||||||
$"file:///{SymbolsConverter.ASCII.EncodeSymbolsOnly(f)}")
|
|
||||||
End With
|
End With
|
||||||
End Function
|
End Function
|
||||||
Private ReadOnly DownloadProgressPattern As RParams = RParams.DMS("\[download\]\s*([\d\.,]+)", 1, EDP.ReturnValue)
|
Private ReadOnly DownloadProgressPattern As RParams = RParams.DMS("\[download\]\s*([\d\.,]+)", 1, EDP.ReturnValue)
|
||||||
@@ -921,23 +989,41 @@ Namespace API.YouTube.Objects
|
|||||||
Dim t As TextSaver = Nothing
|
Dim t As TextSaver = Nothing
|
||||||
Try
|
Try
|
||||||
Dim f As SFile
|
Dim f As SFile
|
||||||
|
Dim arr As M3U8CreationMode() = If(MyYouTubeSettings.MusicPlaylistCreate_CreationMode.Value = M3U8CreationMode.Both,
|
||||||
|
{M3U8CreationMode.Relative, M3U8CreationMode.Absolute},
|
||||||
|
{MyYouTubeSettings.MusicPlaylistCreate_CreationMode.Value})
|
||||||
|
Dim postfix$
|
||||||
|
Dim added As Boolean
|
||||||
|
Dim checkFile As Func(Of IYouTubeMediaContainer, Boolean) = Function(ByVal e As IYouTubeMediaContainer) As Boolean
|
||||||
|
If e.File.Exists Then
|
||||||
|
added = True
|
||||||
|
Return True
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
For Each cm As M3U8CreationMode In arr
|
||||||
|
If arr.Length > 1 AndAlso cm = M3U8CreationMode.Absolute Then postfix = "Abs" Else postfix = String.Empty
|
||||||
|
added = False
|
||||||
If MyYouTubeSettings.MusicPlaylistCreate_M3U8 Then
|
If MyYouTubeSettings.MusicPlaylistCreate_M3U8 Then
|
||||||
t = New TextSaver
|
t = New TextSaver
|
||||||
t.AppendLine("#EXTM3U")
|
t.AppendLine("#EXTM3U")
|
||||||
Elements.ForEach(Sub(e) t.AppendLine(GetPlaylistRow(e)))
|
Elements.ForEach(Sub(e) If checkFile(e) Then t.AppendLine(GetPlaylistRow(e,, cm)))
|
||||||
f = $"{Elements(0).File.PathWithSeparator}Playlist.m3u8"
|
f = $"{Elements(0).File.PathWithSeparator}Playlist{postfix}.m3u8"
|
||||||
t.SaveAs(f, EDP.SendToLog)
|
If added Then t.SaveAs(f, EDP.SendToLog)
|
||||||
If f.Exists Then AddFile(f)
|
If f.Exists Then AddFile(f)
|
||||||
t.Dispose()
|
t.Dispose()
|
||||||
End If
|
End If
|
||||||
|
added = False
|
||||||
If MyYouTubeSettings.MusicPlaylistCreate_M3U Then
|
If MyYouTubeSettings.MusicPlaylistCreate_M3U Then
|
||||||
t = New TextSaver
|
t = New TextSaver
|
||||||
Elements.ForEach(Sub(e) t.AppendLine(e.File))
|
Elements.ForEach(Sub(e) If checkFile(e) Then t.AppendLine(If(cm = M3U8CreationMode.Relative, e.File.File, e.File.ToString)))
|
||||||
f = $"{Elements(0).File.PathWithSeparator}Playlist.m3u"
|
f = $"{Elements(0).File.PathWithSeparator}Playlist{postfix}.m3u"
|
||||||
t.SaveAs(f, EDP.SendToLog)
|
If added Then t.SaveAs(f, EDP.SendToLog)
|
||||||
If f.Exists Then AddFile(f)
|
If f.Exists Then AddFile(f)
|
||||||
t.Dispose()
|
t.Dispose()
|
||||||
End If
|
End If
|
||||||
|
Next
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[YouTubeMediaContainerBase.Download.CreatePlaylist]")
|
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[YouTubeMediaContainerBase.Download.CreatePlaylist]")
|
||||||
End Try
|
End Try
|
||||||
@@ -966,17 +1052,24 @@ Namespace API.YouTube.Objects
|
|||||||
.Visible = True
|
.Visible = True
|
||||||
.Value = 0
|
.Value = 0
|
||||||
.Maximum = DownloadGetElemCountSingle()
|
.Maximum = DownloadGetElemCountSingle()
|
||||||
.Information = $"Download {ObjectType}"
|
.Information = "Downloading"
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Dim cDown As Boolean = False
|
Dim cDown As Boolean = False
|
||||||
|
Dim fCover As SFile = Nothing
|
||||||
|
Dim cUrl$ = String.Empty
|
||||||
For Each elem In Elements
|
For Each elem In Elements
|
||||||
With DirectCast(elem, YouTubeMediaContainerBase)
|
With DirectCast(elem, YouTubeMediaContainerBase)
|
||||||
If Not .CoverDownloaded Then .CoverDownloaded = cDown
|
'If Not .CoverDownloaded Then .CoverDownloaded = cDown
|
||||||
|
.CoverDownloaded = cDown
|
||||||
|
.CoverFile = fCover
|
||||||
|
.CoverURL = cUrl
|
||||||
AddHandler .FileDownloadStarted, fDown
|
AddHandler .FileDownloadStarted, fDown
|
||||||
.Download(UseCookies, Token)
|
.Download(UseCookies, Token)
|
||||||
cDown = .CoverDownloaded
|
cDown = .CoverDownloaded
|
||||||
|
fCover = .CoverFile
|
||||||
|
cUrl = .CoverURL
|
||||||
RemoveHandler .FileDownloadStarted, fDown
|
RemoveHandler .FileDownloadStarted, fDown
|
||||||
End With
|
End With
|
||||||
If Token.IsCancellationRequested Or disposedValue Then Exit For
|
If Token.IsCancellationRequested Or disposedValue Then Exit For
|
||||||
@@ -1003,6 +1096,8 @@ Namespace API.YouTube.Objects
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Protected CoverDownloaded As Boolean = False
|
Protected CoverDownloaded As Boolean = False
|
||||||
|
Protected CoverFile As SFile = Nothing
|
||||||
|
Protected CoverURL As String = String.Empty
|
||||||
Private Sub DownloadPlaylistCover(ByVal PlsId As String, ByVal f As SFile, ByVal UseCookies As Boolean)
|
Private Sub DownloadPlaylistCover(ByVal PlsId As String, ByVal f As SFile, ByVal UseCookies As Boolean)
|
||||||
Try
|
Try
|
||||||
Dim url$ = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={PlsId}"
|
Dim url$ = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={PlsId}"
|
||||||
@@ -1038,7 +1133,8 @@ Namespace API.YouTube.Objects
|
|||||||
url = LinkFormatterSecure(u)
|
url = LinkFormatterSecure(u)
|
||||||
f.Name = "cover"
|
f.Name = "cover"
|
||||||
f.Extension = "jpg"
|
f.Extension = "jpg"
|
||||||
If resp.DownloadFile(url, f, EDP.ReturnValue) And f.Exists Then CoverDownloaded = True : AddFile(f)
|
If resp.DownloadFile(url, f, EDP.ReturnValue) And f.Exists Then _
|
||||||
|
CoverFile = f : CoverURL = url : CoverDownloaded = True : AddFile(f)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Using
|
End Using
|
||||||
@@ -1111,7 +1207,7 @@ Namespace API.YouTube.Objects
|
|||||||
.Value = 0
|
.Value = 0
|
||||||
.Maximum = 100
|
.Maximum = 100
|
||||||
.Provider = ProgressProvider
|
.Provider = ProgressProvider
|
||||||
.Information = $"Download {MediaType}"
|
.Information = "Downloading"
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
.MainProcessName = MyYouTubeSettings.YTDLP.Name '"yt-dlp"
|
.MainProcessName = MyYouTubeSettings.YTDLP.Name '"yt-dlp"
|
||||||
@@ -1143,15 +1239,28 @@ Namespace API.YouTube.Objects
|
|||||||
If fileUrl.Exists Then AddFile(fileUrl)
|
If fileUrl.Exists Then AddFile(fileUrl)
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If MyYouTubeSettings.CreateDescriptionFiles And Not Description.IsEmptyString Then
|
With MyYouTubeSettings
|
||||||
|
If .CreateDescriptionFiles And (Not Description.IsEmptyString Or .CreateDescriptionFiles_CreateWithNoDescription) Then
|
||||||
Dim fileDesr As SFile = File
|
Dim fileDesr As SFile = File
|
||||||
fileDesr.Extension = "txt"
|
fileDesr.Extension = "txt"
|
||||||
TextSaver.SaveTextToFile(Description, fileDesr,,, EDP.None)
|
Using fileDesrText As New TextSaver(fileDesr)
|
||||||
|
fileDesrText.Append($"Uploaded: {DateAdded:yyyy-MM-dd HH:mm:ss}")
|
||||||
|
fileDesrText.AppendLine()
|
||||||
|
fileDesrText.AppendLine($"URL: {URL}")
|
||||||
|
fileDesrText.AppendLine($"Channel name: {AccountName}")
|
||||||
|
fileDesrText.AppendLine($"Channel ID: {UserID}")
|
||||||
|
If Not Description.IsEmptyString Then
|
||||||
|
If Not fileDesrText.IsEmptyString Then fileDesrText.AppendLine.AppendLine()
|
||||||
|
fileDesrText.Append(Description)
|
||||||
|
End If
|
||||||
|
fileDesrText.Save(EDP.None)
|
||||||
|
End Using
|
||||||
If fileDesr.Exists Then AddFile(fileDesr)
|
If fileDesr.Exists Then AddFile(fileDesr)
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
|
|
||||||
If PlaylistCount > 0 And Not CoverDownloaded And Not PlaylistID.IsEmptyString Then DownloadPlaylistCover(PlaylistID, File, UseCookies)
|
If PlaylistCount > 0 And Not CoverDownloaded And Not PlaylistID.IsEmptyString Then DownloadPlaylistCover(PlaylistID, File, UseCookies)
|
||||||
If prExists Then Progress.InformationTemporary = $"Download {MediaType}: post processing"
|
If prExists Then Progress.InformationTemporary = "Downloading: post processing"
|
||||||
_ThumbnailFile = File
|
_ThumbnailFile = File
|
||||||
_ThumbnailFile.Name &= "_thumb"
|
_ThumbnailFile.Name &= "_thumb"
|
||||||
_ThumbnailFile.Extension = "jpg"
|
_ThumbnailFile.Extension = "jpg"
|
||||||
@@ -1173,6 +1282,7 @@ Namespace API.YouTube.Objects
|
|||||||
Dim fPatternFiles$ = $"{File.Name}*." & "{0}"
|
Dim fPatternFiles$ = $"{File.Name}*." & "{0}"
|
||||||
Dim fAacAudio As New TempFileConversion(New SFile(String.Format(fPattern, aac)), Me)
|
Dim fAacAudio As New TempFileConversion(New SFile(String.Format(fPattern, aac)), Me)
|
||||||
Dim mp3ThumbEmbedded As Boolean = False
|
Dim mp3ThumbEmbedded As Boolean = False
|
||||||
|
Dim audioFiles As New List(Of SFile)
|
||||||
|
|
||||||
Dim tempFilesList As New List(Of TempFileConversion)
|
Dim tempFilesList As New List(Of TempFileConversion)
|
||||||
Dim ttFile As TempFileConversion
|
Dim ttFile As TempFileConversion
|
||||||
@@ -1209,10 +1319,10 @@ Namespace API.YouTube.Objects
|
|||||||
End Sub
|
End Sub
|
||||||
Dim embedThumbTo As Action(Of SFile) =
|
Dim embedThumbTo As Action(Of SFile) =
|
||||||
Sub(ByVal dFile As SFile)
|
Sub(ByVal dFile As SFile)
|
||||||
If dFile.Exists And ThumbnailFile.Exists Then
|
If dFile.Exists And CoverFile.IfNullOrEmpty(ThumbnailFile).Exists Then
|
||||||
Dim dFileNew As SFile = dFile
|
Dim dFileNew As SFile = dFile
|
||||||
dFileNew.Name &= "_NEW"
|
dFileNew.Name &= "_NEW"
|
||||||
.Execute($"ffmpeg -i ""{dFile}"" -i ""{ThumbnailFile}"" -map 0:0 -map 1:0 -c copy -id3v2_version 3 -metadata:s:v title=""Cover"" -metadata:s:v comment=""Cover"" ""{dFileNew}""")
|
.Execute($"ffmpeg -i ""{dFile}"" -i ""{CoverFile.IfNullOrEmpty(ThumbnailFile)}"" -map 0:0 -map 1:0 -c copy -id3v2_version 3 -metadata:s:v title=""Cover"" -metadata:s:v comment=""Cover"" ""{dFileNew}""")
|
||||||
If dFileNew.Exists AndAlso dFile.Delete(,, EDP.ReturnValue) Then SFile.Rename(dFileNew, dFile)
|
If dFileNew.Exists AndAlso dFile.Delete(,, EDP.ReturnValue) Then SFile.Rename(dFileNew, dFile)
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
@@ -1280,17 +1390,26 @@ Namespace API.YouTube.Objects
|
|||||||
format = format.StringToLower
|
format = format.StringToLower
|
||||||
f = String.Format(fPattern, format)
|
f = String.Format(fPattern, format)
|
||||||
AddFile(f)
|
AddFile(f)
|
||||||
|
audioFiles.Add(f)
|
||||||
If Not f.Exists Then
|
If Not f.Exists Then
|
||||||
tryToConvert.Invoke(format, f)
|
tryToConvert.Invoke(format, f)
|
||||||
updateBitrate(f)
|
updateBitrate(f)
|
||||||
|
If f.Exists Then
|
||||||
If format = mp3 And Not mp3ThumbEmbedded And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _
|
If format = mp3 And Not mp3ThumbEmbedded And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _
|
||||||
embedThumbTo.Invoke(f) : mp3ThumbEmbedded = True
|
embedThumbTo.Invoke(f) : mp3ThumbEmbedded = True
|
||||||
If Not M3U8_PlaylistFiles.ListExists AndAlso f.Exists Then M3U8_Append(f)
|
If M3U8_PlaylistFiles.ListExists OrElse
|
||||||
|
(format = mp3 AndAlso MyYouTubeSettings.VideoPlaylist_AddExtractedMP3.Value) Then _
|
||||||
|
M3U8_Append(f)
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
'mp3
|
||||||
|
If IsMusic And ObjectType = YouTubeMediaType.Single And File.Extension = mp3 And
|
||||||
|
Not mp3ThumbEmbedded And CoverFile.Exists And MyYouTubeSettings.DefaultAudioEmbedThumbnail_Cover Then embedThumbTo.Invoke(File)
|
||||||
|
|
||||||
'Update video
|
'Update video
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If SelectedVideoIndex >= 0 AndAlso tempFilesList.Count > 0 AndAlso tempFilesList.Exists(Function(tf) tf.ToReplace) Then
|
If SelectedVideoIndex >= 0 AndAlso tempFilesList.Count > 0 AndAlso tempFilesList.Exists(Function(tf) tf.ToReplace) Then
|
||||||
@@ -1310,16 +1429,93 @@ Namespace API.YouTube.Objects
|
|||||||
'Delete unrequsted files
|
'Delete unrequsted files
|
||||||
If tempFilesList.Count > 0 Then tempFilesList.ForEach(Sub(tfr) If Not tfr.Requested Then tfr.File.Delete(,, EDP.None)) : tempFilesList.Clear()
|
If tempFilesList.Count > 0 Then tempFilesList.ForEach(Sub(tfr) If Not tfr.Requested Then tfr.File.Delete(,, EDP.None)) : tempFilesList.Clear()
|
||||||
|
|
||||||
'Update video FPS
|
If SelectedVideoIndex >= 0 Then
|
||||||
If SelectedVideoIndex >= 0 AndAlso OutputVideoFPS > 0 AndAlso SelectedVideo.Bitrate <> OutputVideoFPS Then
|
Dim reencodeFile As Action(Of String) =
|
||||||
|
Sub(ByVal ffmpegCommand As String)
|
||||||
f = File
|
f = File
|
||||||
f.Name &= "tmp00"
|
f.Name &= "tmp00"
|
||||||
.Execute($"ffmpeg -i ""{File}"" -filter:v fps={OutputVideoFPS.ToString.Replace(",", ".")} -c:a copy ""{f}""")
|
.Execute(String.Format(ffmpegCommand, File.ToString, f.ToString))
|
||||||
If f.Exists Then
|
If f.Exists Then
|
||||||
|
If f.Size > 0 Then
|
||||||
File.Delete()
|
File.Delete()
|
||||||
SFile.Rename(f, File,, EDP.LogMessageValue)
|
SFile.Rename(f, File,, EDP.LogMessageValue)
|
||||||
|
Else
|
||||||
|
f.Delete(, SFODelete.DeletePermanently, EDP.None)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
End Sub
|
||||||
|
'Change video codec to AVC
|
||||||
|
If MyYouTubeSettings.DefaultVideoConvertNonAVC.Value AndAlso
|
||||||
|
Not SelectedVideo.Codec.IsEmptyString AndAlso Not SelectedVideo.Codec.Trim.ToLower.StartsWith("avc") Then _
|
||||||
|
reencodeFile("ffmpeg -i ""{0}"" -c:a copy -c:v libx264 ""{1}""")
|
||||||
|
|
||||||
|
'Update video FPS
|
||||||
|
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 trimSingleReplace As Boolean = TrimOptions.Count = 1 And TrimDeleteOriginalFile
|
||||||
|
Dim audioReplace As New Dictionary(Of SFile, SFile)
|
||||||
|
Dim processTrim As Action(Of TrimOption, SFile, Boolean) =
|
||||||
|
Sub(ByVal opt As TrimOption, ByVal pFile As SFile, ByVal isAudio As Boolean)
|
||||||
|
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
|
||||||
|
If Not trimSingleReplace Then AddFile(fNew)
|
||||||
|
If isAudio And trimSingleReplace And Not audioReplace.ContainsKey(pFile) Then audioReplace.Add(pFile, fNew)
|
||||||
|
If format = mp3 And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _
|
||||||
|
embedThumbTo.Invoke(fNew) : mp3ThumbEmbedded = True
|
||||||
|
If Not trimSingleReplace AndAlso
|
||||||
|
(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, False)
|
||||||
|
If audioFiles.Count > 0 Then
|
||||||
|
For Each f In audioFiles : processTrim(tr, f, True) : Next
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
If TrimDeleteOriginalFile Then
|
||||||
|
Dim silentEDP As New ErrorsDescriber(EDP.ReturnValue)
|
||||||
|
File.Delete(,, silentEDP)
|
||||||
|
If trimSingleReplace Then
|
||||||
|
File = SFile.Rename(trimFirstFile, File,, New ErrorsDescriber(False, False, False, trimFirstFile))
|
||||||
|
If audioReplace.Count > 0 Then
|
||||||
|
For Each kvf As KeyValuePair(Of SFile, SFile) In audioReplace
|
||||||
|
If kvf.Key.Exists And kvf.Value.Exists Then
|
||||||
|
kvf.Key.Delete(,, silentEDP)
|
||||||
|
SFile.Rename(kvf.Value, kvf.Key,, silentEDP)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
audioReplace.Clear()
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
File = trimFirstFile
|
||||||
|
If audioFiles.Count > 0 Then
|
||||||
|
For Each f In audioFiles
|
||||||
|
If Not f = File Then f.Delete(,, silentEDP)
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End With
|
End With
|
||||||
@@ -1534,7 +1730,7 @@ Namespace API.YouTube.Objects
|
|||||||
ID = .Value("id")
|
ID = .Value("id")
|
||||||
Title = TitleHtmlConverter.Invoke(.Value("title"))
|
Title = TitleHtmlConverter.Invoke(.Value("title"))
|
||||||
Description = .Value("description")
|
Description = .Value("description")
|
||||||
URL = .Value("webpage_url")
|
URL = .Value("webpage_url").ToMusicUrl(IsMusic)
|
||||||
|
|
||||||
PlaylistID = .Value("playlist_id")
|
PlaylistID = .Value("playlist_id")
|
||||||
PlaylistCount = .Value("n_entries").IfNullOrEmpty(.Value("playlist_count")).FromXML(Of Integer)(0)
|
PlaylistCount = .Value("n_entries").IfNullOrEmpty(.Value("playlist_count")).FromXML(Of Integer)(0)
|
||||||
@@ -1547,12 +1743,20 @@ Namespace API.YouTube.Objects
|
|||||||
If Not tmpPls.IsEmptyString Then PlaylistTitle = tmpPls
|
If Not tmpPls.IsEmptyString Then PlaylistTitle = tmpPls
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
Dim tmpTitle$
|
||||||
UserID = .Value("uploader_id")
|
UserID = .Value("uploader_id")
|
||||||
UserTitle = TitleHtmlConverter.Invoke(.Value("uploader"))
|
UserTitle = TitleHtmlConverter.Invoke(.Value("uploader"))
|
||||||
If Not UserTitle.IsEmptyString Then
|
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
|
If Not tmpTitle.IsEmptyString Then UserTitle = tmpTitle
|
||||||
End If
|
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,
|
Dim ext$ = IIf(IsMusic,
|
||||||
MyYouTubeSettings.DefaultAudioCodecMusic.Value.StringToLower,
|
MyYouTubeSettings.DefaultAudioCodecMusic.Value.StringToLower,
|
||||||
@@ -1572,12 +1776,15 @@ Namespace API.YouTube.Objects
|
|||||||
If tValue.HasValue Then Duration = TimeSpan.FromSeconds(tValue.Value)
|
If tValue.HasValue Then Duration = TimeSpan.FromSeconds(tValue.Value)
|
||||||
End If
|
End If
|
||||||
DateAdded = AConvert(Of Date)(.Value("release_date").IfNullOrEmpty(.Value("upload_date")), DateAddedProvider, New Date)
|
DateAdded = AConvert(Of Date)(.Value("release_date").IfNullOrEmpty(.Value("upload_date")), DateAddedProvider, New Date)
|
||||||
|
If Not IsMusic Then FileDateUpdate()
|
||||||
|
|
||||||
ParseFormats(.Self)
|
ParseFormats(.Self)
|
||||||
|
|
||||||
ParseThumbnails(.Self)
|
ParseThumbnails(.Self)
|
||||||
|
|
||||||
ParseSubtitles(.Self)
|
ParseSubtitles(.Self)
|
||||||
|
|
||||||
|
ParseChapters(.Self)
|
||||||
End With
|
End With
|
||||||
Return True
|
Return True
|
||||||
End If
|
End If
|
||||||
@@ -1647,8 +1854,12 @@ Namespace API.YouTube.Objects
|
|||||||
If If(e({"formats"})?.Count, 0) > 0 Then
|
If If(e({"formats"})?.Count, 0) > 0 Then
|
||||||
Dim obj As MediaObject
|
Dim obj As MediaObject
|
||||||
Dim nValue#
|
Dim nValue#
|
||||||
Dim sValue$
|
Dim sValue$ = String.Empty
|
||||||
Dim validCodecValue As Func(Of String, Boolean) = Function(codec) Not codec.IsEmptyString AndAlso Not codec = "none"
|
Dim allowWebm As Boolean = MyYouTubeSettings.DefaultVideoAllowWebm
|
||||||
|
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"})
|
For Each ee In e({"formats"})
|
||||||
obj = New MediaObject With {
|
obj = New MediaObject With {
|
||||||
@@ -1672,19 +1883,30 @@ Namespace API.YouTube.Objects
|
|||||||
If obj.Size <= 0 And obj.Bitrate > 0 And Duration.TotalSeconds > 0 Then _
|
If obj.Size <= 0 And obj.Bitrate > 0 And Duration.TotalSeconds > 0 Then _
|
||||||
obj.Size = (obj.Bitrate / 8 * Duration.TotalSeconds).RoundVal(2)
|
obj.Size = (obj.Bitrate / 8 * Duration.TotalSeconds).RoundVal(2)
|
||||||
|
|
||||||
sValue = ee.Value("vcodec")
|
'sValue = ee.Value("vcodec")
|
||||||
If validCodecValue(sValue) Then
|
If validCodecValue(ee.Value("vcodec")) Then
|
||||||
obj.Type = UMTypes.Video
|
obj.Type = UMTypes.Video
|
||||||
obj.Codec = sValue.Split(".").First
|
obj.Codec = sValue.Split(".").First
|
||||||
If validCodecValue(ee.Value("acodec")) Then obj.Type = av
|
If validCodecValue(ee.Value("acodec")) Then obj.Type = av
|
||||||
Else
|
ElseIf validCodecValue(ee.Value("acodec")) Then
|
||||||
sValue = ee.Value("acodec")
|
|
||||||
If validCodecValue(sValue) Then
|
|
||||||
obj.Type = UMTypes.Audio
|
obj.Type = UMTypes.Audio
|
||||||
obj.Codec = sValue.Split(".").First
|
obj.Codec = sValue.Split(".").First
|
||||||
Else
|
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 If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
If Not fd Then Continue For
|
||||||
End If
|
End If
|
||||||
MediaObjects.Add(obj)
|
MediaObjects.Add(obj)
|
||||||
Next
|
Next
|
||||||
@@ -1696,14 +1918,18 @@ Namespace API.YouTube.Objects
|
|||||||
Dim data As New List(Of MediaObject)(MediaObjects.Where(Function(mo) mo.Type = t And mo.Extension = webm))
|
Dim data As New List(Of MediaObject)(MediaObjects.Where(Function(mo) mo.Type = t And mo.Extension = webm))
|
||||||
If data.Count > 0 Then
|
If data.Count > 0 Then
|
||||||
Dim d As MediaObject = Nothing
|
Dim d As MediaObject = Nothing
|
||||||
Dim expWebm As Predicate(Of MediaObject) = Function(mo) mo.Extension = webm
|
Dim allWebm As Boolean = False, allAVC As Boolean = False
|
||||||
Dim expAVC As Predicate(Of MediaObject) = Function(mo) mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
|
Dim expWebm As Predicate(Of MediaObject) = Function(mo) Not allWebm And mo.Extension = webm
|
||||||
Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean) =
|
Dim expAVC As Predicate(Of MediaObject) = Function(mo) Not allAVC And mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
|
||||||
Function(mo, exp, isTrue) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width
|
Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean, Boolean) =
|
||||||
Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False)
|
Function(mo, exp, isTrue, checkHttp) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width And
|
||||||
Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True)
|
(Not checkHttp OrElse mo.ProtocolType = Protocols.https)
|
||||||
Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True)
|
Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False, allowWebm)
|
||||||
Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False)
|
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
|
For Each d In data
|
||||||
If MediaObjects.Count = 0 Then Exit For
|
If MediaObjects.Count = 0 Then Exit For
|
||||||
If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm)
|
If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm)
|
||||||
@@ -1824,6 +2050,15 @@ Namespace API.YouTube.Objects
|
|||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
End Sub
|
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
|
#End Region
|
||||||
#Region "IEContainerProvider Support"
|
#Region "IEContainerProvider Support"
|
||||||
Private Function GetElementsChecked() As IEnumerable(Of EContainer)
|
Private Function GetElementsChecked() As IEnumerable(Of EContainer)
|
||||||
@@ -1898,6 +2133,8 @@ Namespace API.YouTube.Objects
|
|||||||
_Subtitles.Clear()
|
_Subtitles.Clear()
|
||||||
_SubtitlesDelegated.Clear()
|
_SubtitlesDelegated.Clear()
|
||||||
SubtitlesSelectedIndexes.Clear()
|
SubtitlesSelectedIndexes.Clear()
|
||||||
|
Chapters.Clear()
|
||||||
|
TrimOptions.Clear()
|
||||||
MediaObjects.Clear()
|
MediaObjects.Clear()
|
||||||
_Files.Clear()
|
_Files.Clear()
|
||||||
PostProcessing_OutputAudioFormats.Clear()
|
PostProcessing_OutputAudioFormats.Clear()
|
||||||
|
|||||||
@@ -115,18 +115,46 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Attributes\GridVisibleAttribute.vb" />
|
<Compile Include="Attributes\GridVisibleAttribute.vb" />
|
||||||
<Compile Include="Base\TableControlsProcessor.vb" />
|
<Compile Include="Base\TableControlsProcessor.vb" />
|
||||||
|
<Compile Include="Controls\ButtonRC.vb">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Controls\ChannelTabsChooserForm.Designer.vb">
|
<Compile Include="Controls\ChannelTabsChooserForm.Designer.vb">
|
||||||
<DependentUpon>ChannelTabsChooserForm.vb</DependentUpon>
|
<DependentUpon>ChannelTabsChooserForm.vb</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\ChannelTabsChooserForm.vb">
|
<Compile Include="Controls\ChannelTabsChooserForm.vb">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</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">
|
<Compile Include="Controls\PlayListParserForm.Designer.vb">
|
||||||
<DependentUpon>PlayListParserForm.vb</DependentUpon>
|
<DependentUpon>PlayListParserForm.vb</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\PlayListParserForm.vb">
|
<Compile Include="Controls\PlayListParserForm.vb">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</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\DownloadLocationsCollection.vb" />
|
||||||
<Compile Include="Downloader\IDownloaderSettings.vb" />
|
<Compile Include="Downloader\IDownloaderSettings.vb" />
|
||||||
<Compile Include="Downloader\Notificator.vb" />
|
<Compile Include="Downloader\Notificator.vb" />
|
||||||
@@ -217,9 +245,21 @@
|
|||||||
<EmbeddedResource Include="Controls\ChannelTabsChooserForm.resx">
|
<EmbeddedResource Include="Controls\ChannelTabsChooserForm.resx">
|
||||||
<DependentUpon>ChannelTabsChooserForm.vb</DependentUpon>
|
<DependentUpon>ChannelTabsChooserForm.vb</DependentUpon>
|
||||||
</EmbeddedResource>
|
</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">
|
<EmbeddedResource Include="Controls\PlayListParserForm.resx">
|
||||||
<DependentUpon>PlayListParserForm.vb</DependentUpon>
|
<DependentUpon>PlayListParserForm.vb</DependentUpon>
|
||||||
</EmbeddedResource>
|
</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">
|
<EmbeddedResource Include="Downloader\MediaItem.resx">
|
||||||
<DependentUpon>MediaItem.vb</DependentUpon>
|
<DependentUpon>MediaItem.vb</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
|
|||||||
<Assembly: AssemblyDescription("SCrawler YouTube downloader")>
|
<Assembly: AssemblyDescription("SCrawler YouTube downloader")>
|
||||||
<Assembly: AssemblyCompany("AndyProgram")>
|
<Assembly: AssemblyCompany("AndyProgram")>
|
||||||
<Assembly: AssemblyProduct("SCrawler.YouTubeDownloader")>
|
<Assembly: AssemblyProduct("SCrawler.YouTubeDownloader")>
|
||||||
<Assembly: AssemblyCopyright("Copyright © 2024")>
|
<Assembly: AssemblyCopyright("Copyright © 2026")>
|
||||||
<Assembly: AssemblyTrademark("AndyProgram")>
|
<Assembly: AssemblyTrademark("AndyProgram")>
|
||||||
|
|
||||||
<Assembly: ComVisible(False)>
|
<Assembly: ComVisible(False)>
|
||||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2024.5.4.0")>
|
<Assembly: AssemblyVersion("2025.11.25.0")>
|
||||||
<Assembly: AssemblyFileVersion("2024.5.4.0")>
|
<Assembly: AssemblyFileVersion("2025.11.25.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
14
SCrawler.sln
@@ -29,6 +29,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Updater", "SCrawle
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Shared", "SCrawler.Shared\SCrawler.Shared.vbproj", "{DC634700-24C7-42DD-BF8F-87E6CC54E625}"
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Shared", "SCrawler.Shared\SCrawler.Shared.vbproj", "{DC634700-24C7-42DD-BF8F-87E6CC54E625}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PersonalUtilities.Images", "..\..\MyUtilities\PersonalUtilities.Images\PersonalUtilities.Images.vbproj", "{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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|x64.Build.0 = Release|x64
|
||||||
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.ActiveCfg = Release|x86
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.ActiveCfg = Release|x86
|
||||||
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ Namespace API.Base
|
|||||||
Friend Const Header_Authorization As String = "authorization"
|
Friend Const Header_Authorization As String = "authorization"
|
||||||
Friend Const Header_CSRFToken As String = "x-csrf-token"
|
Friend Const Header_CSRFToken As String = "x-csrf-token"
|
||||||
|
|
||||||
|
Friend Const CAT_UserDefs As String = "New user defaults"
|
||||||
|
Friend Const CAT_Timers As String = "Timers"
|
||||||
|
|
||||||
Friend Const ConcurrentDownloadsCaption As String = "Concurrent downloads"
|
Friend Const ConcurrentDownloadsCaption As String = "Concurrent downloads"
|
||||||
Friend Const ConcurrentDownloadsToolTip As String = "The number of concurrent downloads."
|
Friend Const ConcurrentDownloadsToolTip As String = "The number of concurrent downloads."
|
||||||
Friend Const SavedPostsUserNameCaption As String = "Saved posts user"
|
Friend Const SavedPostsUserNameCaption As String = "Saved posts user"
|
||||||
@@ -25,6 +28,15 @@ Namespace API.Base
|
|||||||
Friend Const GifsDownloadCaption As String = "Download GIFs"
|
Friend Const GifsDownloadCaption As String = "Download GIFs"
|
||||||
Friend Const UseMD5ComparisonCaption As String = "Use MD5 comparison"
|
Friend Const UseMD5ComparisonCaption As String = "Use MD5 comparison"
|
||||||
Friend Const UseMD5ComparisonToolTip As String = "Each image will be checked for existence using MD5"
|
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()
|
Private Sub New()
|
||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
'
|
'
|
||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports System.Net
|
Imports SCrawler.Plugin
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
Namespace API.Base
|
Namespace API.Base
|
||||||
Friend NotInheritable Class DownDetector
|
Friend NotInheritable Class DownDetector
|
||||||
Private Shared ReadOnly Property Params As New RParams("x:.'([\S]+?)',.y:.(\d+)", -1, Nothing, RegexReturn.List)
|
Private Shared ReadOnly Property Params As New RParams("x:.'([\S]+?)',.y:.(\d+)", -1, Nothing, RegexReturn.List)
|
||||||
@@ -34,8 +35,7 @@ Namespace API.Base
|
|||||||
Try
|
Try
|
||||||
Dim l As List(Of Data) = Nothing
|
Dim l As List(Of Data) = Nothing
|
||||||
Dim l2 As List(Of Data) = Nothing
|
Dim l2 As List(Of Data) = Nothing
|
||||||
Using w As New WebClient
|
Dim r$ = GetWebString($"https://downdetector.co.uk/status/{Site}/",, EDP.ThrowException)
|
||||||
Dim r$ = w.DownloadString($"https://downdetector.co.uk/status/{Site}/")
|
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
l = RegexFields(Of Data)(r, {Params}, {1, 2})
|
l = RegexFields(Of Data)(r, {Params}, {1, 2})
|
||||||
If l.ListExists(2) Then
|
If l.ListExists(2) Then
|
||||||
@@ -43,7 +43,7 @@ Namespace API.Base
|
|||||||
l2 = New List(Of Data)
|
l2 = New List(Of Data)
|
||||||
Dim d As Data
|
Dim d As Data
|
||||||
Dim eDates As New List(Of Date)
|
Dim eDates As New List(Of Date)
|
||||||
Dim MaxValue As Func(Of Date, Integer) = Function(dd) (From ddd In l Where ddd.Date = dd Select ddd.Value).DefaultIfEmpty(0).Max
|
Dim MaxValue As Func(Of Date, Integer) = Function(dd) (From ddd As Data In l Where ddd.Date = dd Select ddd.Value).DefaultIfEmpty(0).Max
|
||||||
For i% = 0 To l.Count - 1
|
For i% = 0 To l.Count - 1
|
||||||
If Not eDates.Contains(l(i).Date) Then
|
If Not eDates.Contains(l(i).Date) Then
|
||||||
d = l(i)
|
d = l(i)
|
||||||
@@ -57,11 +57,84 @@ Namespace API.Base
|
|||||||
l2.Sort()
|
l2.Sort()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Using
|
|
||||||
Return l2
|
Return l2
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"[DownDetector.GetData({Site})]")
|
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"[DownDetector.GetData({Site})]")
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
|
Friend Interface IDownDetector
|
||||||
|
ReadOnly Property Value As Integer
|
||||||
|
ReadOnly Property AddToLog As Boolean
|
||||||
|
ReadOnly Property CheckSite As String
|
||||||
|
Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean
|
||||||
|
End Interface
|
||||||
|
Friend Class Checker(Of T As {ISiteSettings, IDownDetector})
|
||||||
|
Protected ReadOnly Property Source As T
|
||||||
|
Private ReadOnly NP As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||||
|
Friend Sub New(ByRef _Source As T)
|
||||||
|
Source = _Source
|
||||||
|
End Sub
|
||||||
|
Private ____AvailableChecked As Boolean = False
|
||||||
|
Private ____AvailableResult As Boolean = False
|
||||||
|
Friend Overridable Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean
|
||||||
|
If Settings.DownDetectorEnabled And Source.Value >= 0 Then
|
||||||
|
If Not ____AvailableChecked Then
|
||||||
|
____AvailableResult = AvailableImpl(What, Silent)
|
||||||
|
____AvailableChecked = True
|
||||||
|
End If
|
||||||
|
Return ____AvailableResult
|
||||||
|
Else
|
||||||
|
Return True
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Protected Overridable Function AvailableImpl(ByVal What As Download, ByVal Silent As Boolean) As Boolean
|
||||||
|
Try
|
||||||
|
Source.AvailableText = String.Empty
|
||||||
|
If Source.Value < 0 Then
|
||||||
|
Return True
|
||||||
|
Else
|
||||||
|
Dim dl As List(Of Data) = GetData(Source.CheckSite)
|
||||||
|
If dl.ListExists Then
|
||||||
|
dl = dl.Take(4).ToList
|
||||||
|
Dim avg% = dl.Average(Function(d) d.Value)
|
||||||
|
If avg > Source.Value Then
|
||||||
|
Source.AvailableText = $"Over the past hour, {Source.Site} has received an average of {avg.NumToString(NP)} outage reports:{vbCr}{dl.ListToString(vbCr)}"
|
||||||
|
If Source.AddToLog Then MyMainLOG = Source.AvailableText
|
||||||
|
If Silent Then
|
||||||
|
Return AvailableImpl_FALSE_SILENT()
|
||||||
|
Else
|
||||||
|
If MsgBoxE({$"{Source.AvailableText}{vbCr}{vbCr}Do you want to continue parsing {Source.Site} data?",
|
||||||
|
$"There are outage reports on {Source.Site}"}, vbYesNo) = vbYes Then
|
||||||
|
Return AvailableImpl_FALSE_SILENT_NOT_MSG_YES()
|
||||||
|
Else
|
||||||
|
Return AvailableImpl_FALSE_SILENT_NOT_MSG_NO()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return AvailableImpl_TRUE()
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"[API.{Source.Site}.SiteSettings.Available([DownDetector])]", True)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Protected Overridable Function AvailableImpl_TRUE() As Boolean
|
||||||
|
Return True
|
||||||
|
End Function
|
||||||
|
Protected Overridable Function AvailableImpl_FALSE_SILENT() As Boolean
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
Protected Overridable Function AvailableImpl_FALSE_SILENT_NOT_MSG_YES() As Boolean
|
||||||
|
Return True
|
||||||
|
End Function
|
||||||
|
Protected Overridable Function AvailableImpl_FALSE_SILENT_NOT_MSG_NO() As Boolean
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
Friend Overridable Sub Reset()
|
||||||
|
____AvailableChecked = False
|
||||||
|
____AvailableResult = False
|
||||||
|
Source.AvailableText = String.Empty
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
46
SCrawler/API/Base/EditorExchangeOptionsBase.vb
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
' 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
|
||||||
|
Imports DN = SCrawler.API.Base.DeclaredNames
|
||||||
|
Namespace API.Base
|
||||||
|
Friend Class EditorExchangeOptionsBase
|
||||||
|
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
@@ -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
|
||||||
@@ -6,73 +6,12 @@
|
|||||||
'
|
'
|
||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports PersonalUtilities.Tools
|
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
|
||||||
Namespace API.Base.GDL
|
Namespace API.Base.GDL
|
||||||
Friend Module Declarations
|
|
||||||
Private Structure GDLURL : Implements IRegExCreator
|
|
||||||
Private _URL As String
|
|
||||||
Friend ReadOnly Property URL As String
|
|
||||||
Get
|
|
||||||
Return _URL
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Public Shared Widening Operator CType(ByVal u As String) As GDLURL
|
|
||||||
Return New GDLURL With {._URL = u}
|
|
||||||
End Operator
|
|
||||||
Public Shared Widening Operator CType(ByVal u As GDLURL) As String
|
|
||||||
Return u.URL
|
|
||||||
End Operator
|
|
||||||
Private Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
|
|
||||||
If ParamsArray.ListExists(2) Then
|
|
||||||
Dim u$ = ParamsArray(0).StringTrim.StringTrimEnd("/"), u2$
|
|
||||||
If Not u.IsEmptyString Then
|
|
||||||
u2 = ParamsArray(1).StringTrim
|
|
||||||
If Not u2.IsEmptyString AndAlso u2.StartsWith("GET", StringComparison.OrdinalIgnoreCase) Then
|
|
||||||
u2 = u2.Remove(0, 3).StringTrim.StringTrimStart("/")
|
|
||||||
If Not u2.IsEmptyString Then _URL = $"{u}/{u2}"
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
Return Me
|
|
||||||
End Function
|
|
||||||
Public Shared Operator =(ByVal x As GDLURL, ByVal y As GDLURL) As Boolean
|
|
||||||
Return x.URL = y.URL
|
|
||||||
End Operator
|
|
||||||
Public Shared Operator <>(ByVal x As GDLURL, ByVal y As GDLURL) As Boolean
|
|
||||||
Return Not x.URL = y.URL
|
|
||||||
End Operator
|
|
||||||
Public Overrides Function ToString() As String
|
|
||||||
Return URL
|
|
||||||
End Function
|
|
||||||
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
|
||||||
Return URL = CType(Obj, String)
|
|
||||||
End Function
|
|
||||||
End Structure
|
|
||||||
Private ReadOnly Property GdlUrlPattern As RParams = RParams.DM(GDLBatch.UrlLibStart.Replace("[", "\[").Replace("]", "\]") &
|
|
||||||
"([^""]+?)""(GET [^""]+)""", 0, EDP.ReturnValue)
|
|
||||||
Friend Function GetUrlsFromGalleryDl(ByVal Batch As BatchExecutor, ByVal Command As String) As List(Of String)
|
|
||||||
Dim urls As New List(Of String)
|
|
||||||
Dim u As GDLURL
|
|
||||||
With Batch
|
|
||||||
.Execute(Command)
|
|
||||||
If .ErrorOutputData.Count > 0 Then
|
|
||||||
For Each eValue$ In .ErrorOutputData
|
|
||||||
u = RegexFields(Of GDLURL)(eValue, {GdlUrlPattern}, {1, 2}, EDP.ReturnValue).ListIfNothing.FirstOrDefault
|
|
||||||
If Not u.URL.IsEmptyString Then urls.ListAddValue(u, LNC)
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
End With
|
|
||||||
Return urls
|
|
||||||
End Function
|
|
||||||
End Module
|
|
||||||
Friend Class GDLBatch : Inherits TokenBatch
|
Friend Class GDLBatch : Inherits TokenBatch
|
||||||
Friend Const UrlLibStart As String = "[urllib3.connectionpool][debug]"
|
Friend Const UrlLibStart As String = "[urllib3.connectionpool][debug]"
|
||||||
Friend Const UrlTextStart As String = UrlLibStart & " https"
|
Friend Const UrlTextStart As String = UrlLibStart & " https"
|
||||||
Friend Sub New(ByVal _Token As Threading.CancellationToken)
|
Friend Sub New(ByVal _Token As Threading.CancellationToken, Optional ByVal __MainProcessName As String = Nothing, Optional ByVal WorkingDir As SFile = Nothing)
|
||||||
MyBase.New(_Token)
|
MyBase.New(_Token, __MainProcessName.IfNullOrEmpty(Settings.GalleryDLFile.File.Name), WorkingDir.IfNullOrEmpty(Settings.GalleryDLFile.File))
|
||||||
MainProcessName = "gallery-dl"
|
|
||||||
ChangeDirectory(Settings.GalleryDLFile.File)
|
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Async Sub OutputDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
|
Protected Overrides Async Sub OutputDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
|
||||||
If Not ProcessKilled Then
|
If Not ProcessKilled Then
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Namespace API.Base
|
|||||||
End Enum
|
End Enum
|
||||||
ReadOnly Property Site As String
|
ReadOnly Property Site As String
|
||||||
ReadOnly Property Name As String
|
ReadOnly Property Name As String
|
||||||
|
Property NameTrue As String
|
||||||
Property ID As String
|
Property ID As String
|
||||||
Property Options As String
|
Property Options As String
|
||||||
Property FriendlyName As String
|
Property FriendlyName As String
|
||||||
@@ -56,6 +57,7 @@ Namespace API.Base
|
|||||||
Property FileExists As Boolean
|
Property FileExists As Boolean
|
||||||
Property DownloadedPictures(ByVal Total As Boolean) As Integer
|
Property DownloadedPictures(ByVal Total As Boolean) As Integer
|
||||||
Property DownloadedVideos(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 DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
|
||||||
ReadOnly Property DownloadedInformation As String
|
ReadOnly Property DownloadedInformation As String
|
||||||
Property HasError As Boolean
|
Property HasError As Boolean
|
||||||
@@ -77,7 +79,7 @@ Namespace API.Base
|
|||||||
''' </summary>
|
''' </summary>
|
||||||
Function Delete(Optional ByVal Multiple As Boolean = False, Optional ByVal CollectionValue As Integer = -1) As Integer
|
Function Delete(Optional ByVal Multiple As Boolean = False, Optional ByVal CollectionValue As Integer = -1) As Integer
|
||||||
Function EraseData(ByVal Mode As EraseMode) As Boolean
|
Function EraseData(ByVal Mode As EraseMode) As Boolean
|
||||||
Function MoveFiles(ByVal CollectionName As String, ByVal SpecialCollectionPath As SFile) As Boolean
|
Function MoveFiles(ByVal CollectionName As String, ByVal SpecialCollectionPath As SFile, Optional ByVal NewUser As SplitCollectionUserInfo? = Nothing) As Boolean
|
||||||
Function CopyFiles(ByVal DestinationPath As SFile, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
|
Function CopyFiles(ByVal DestinationPath As SFile, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
|
||||||
Sub OpenFolder()
|
Sub OpenFolder()
|
||||||
Property DownloadTopCount As Integer?
|
Property DownloadTopCount As Integer?
|
||||||
|
|||||||
@@ -54,9 +54,8 @@ Namespace API.Base
|
|||||||
Dim aStr$ = String.Empty
|
Dim aStr$ = String.Empty
|
||||||
If Count > 1 Then aStr = $" ({Number}/{Count})"
|
If Count > 1 Then aStr = $" ({Number}/{Count})"
|
||||||
Try
|
Try
|
||||||
If Host.Source.ReadyToDownload(PDownload.SavedPosts) Then
|
|
||||||
If Host.Available(PDownload.SavedPosts, Multiple Or Count > 1) Then
|
If Host.Available(PDownload.SavedPosts, Multiple Or Count > 1) Then
|
||||||
Host.DownloadStarted(PDownload.SavedPosts)
|
If Host.Source.ReadyToDownload(PDownload.SavedPosts) Then
|
||||||
If Count > 1 Then Progress.Information = $"{Host.Name} - {Host.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}"
|
If Count > 1 Then Progress.Information = $"{Host.Name} - {Host.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}"
|
||||||
Using user As IUserData = Host.GetInstance(PDownload.SavedPosts, Nothing, False, False)
|
Using user As IUserData = Host.GetInstance(PDownload.SavedPosts, Nothing, False, False)
|
||||||
If Not user Is Nothing Then
|
If Not user Is Nothing Then
|
||||||
@@ -83,11 +82,11 @@ Namespace API.Base
|
|||||||
End Using
|
End Using
|
||||||
Else
|
Else
|
||||||
_Unavailable += 1
|
_Unavailable += 1
|
||||||
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is unavailable"
|
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is not ready"
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
_NotReady += 1
|
_NotReady += 1
|
||||||
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is not ready"
|
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is unavailable"
|
||||||
End If
|
End If
|
||||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
_ErrorCount += 1
|
_ErrorCount += 1
|
||||||
@@ -96,9 +95,6 @@ Namespace API.Base
|
|||||||
_ErrorCount += 1
|
_ErrorCount += 1
|
||||||
Progress.InformationTemporary = $"{Host.Name}{aStr} downloading error"
|
Progress.InformationTemporary = $"{Host.Name}{aStr} downloading error"
|
||||||
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[API.Base.ProfileSaved.Download({Host.Key}{aStr})]")
|
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[API.Base.ProfileSaved.Download({Host.Key}{aStr})]")
|
||||||
Finally
|
|
||||||
Host.DownloadDone(PDownload.SavedPosts)
|
|
||||||
MainFrameObj.UpdateLogButton()
|
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Imports PersonalUtilities.Tools.Web.Cookies
|
|||||||
Imports PersonalUtilities.Tools.Web.Clients
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Imports DN = SCrawler.API.Base.DeclaredNames
|
||||||
Namespace API.Base
|
Namespace API.Base
|
||||||
Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer
|
Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer
|
||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
@@ -33,7 +34,17 @@ Namespace API.Base
|
|||||||
End Property
|
End Property
|
||||||
Friend Property AccountName As String Implements ISiteSettings.AccountName
|
Friend Property AccountName As String Implements ISiteSettings.AccountName
|
||||||
Friend Property Temporary As Boolean = False Implements ISiteSettings.Temporary
|
Friend Property Temporary As Boolean = False Implements ISiteSettings.Temporary
|
||||||
Friend Property DefaultInstance As ISiteSettings = Nothing Implements ISiteSettings.DefaultInstance
|
Friend Overridable Property DefaultInstance As ISiteSettings = Nothing Implements ISiteSettings.DefaultInstance
|
||||||
|
Protected _UserAgentDefault As String = String.Empty
|
||||||
|
Friend Overridable Property UserAgentDefault As String Implements ISiteSettings.UserAgentDefault
|
||||||
|
Get
|
||||||
|
Return _UserAgentDefault
|
||||||
|
End Get
|
||||||
|
Set(ByVal _UserAgentDefault As String)
|
||||||
|
Me._UserAgentDefault = _UserAgentDefault
|
||||||
|
If _AllowUserAgentUpdate And Not Responser Is Nothing And Not _UserAgentDefault.IsEmptyString Then Responser.UserAgent = _UserAgentDefault
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
Protected _AllowUserAgentUpdate As Boolean = True
|
Protected _AllowUserAgentUpdate As Boolean = True
|
||||||
Protected _SubscriptionsAllowed As Boolean = False
|
Protected _SubscriptionsAllowed As Boolean = False
|
||||||
Friend ReadOnly Property SubscriptionsAllowed As Boolean Implements ISiteSettings.SubscriptionsAllowed
|
Friend ReadOnly Property SubscriptionsAllowed As Boolean Implements ISiteSettings.SubscriptionsAllowed
|
||||||
@@ -45,6 +56,11 @@ Namespace API.Base
|
|||||||
Friend Overridable ReadOnly Property Responser As Responser
|
Friend Overridable ReadOnly Property Responser As Responser
|
||||||
Private _UserOptionsExists As Boolean = False
|
Private _UserOptionsExists As Boolean = False
|
||||||
Private _UserOptionsType As Type = Nothing
|
Private _UserOptionsType As Type = Nothing
|
||||||
|
Protected Overridable Function UserOptionsValid(ByVal Options As Object) As Boolean
|
||||||
|
Return True
|
||||||
|
End Function
|
||||||
|
Protected Overridable Sub UserOptionsSetParameters(ByRef Options As Object)
|
||||||
|
End Sub
|
||||||
Protected Property UserOptionsType As Type
|
Protected Property UserOptionsType As Type
|
||||||
Get
|
Get
|
||||||
Return _UserOptionsType
|
Return _UserOptionsType
|
||||||
@@ -54,6 +70,14 @@ Namespace API.Base
|
|||||||
_UserOptionsExists = Not t Is Nothing
|
_UserOptionsExists = Not t Is Nothing
|
||||||
End Set
|
End Set
|
||||||
End Property
|
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
|
#End Region
|
||||||
#Region "EnvironmentPrograms"
|
#Region "EnvironmentPrograms"
|
||||||
Private Property CMDEncoding As String Implements ISiteSettings.CMDEncoding
|
Private Property CMDEncoding As String Implements ISiteSettings.CMDEncoding
|
||||||
@@ -109,6 +133,9 @@ Namespace API.Base
|
|||||||
_Image = __Image
|
_Image = __Image
|
||||||
Responser = New Responser With {.DeclaredError = EDP.ThrowException}
|
Responser = New Responser With {.DeclaredError = EDP.ThrowException}
|
||||||
SettingsVersion = New PropertyValue(0)
|
SettingsVersion = New PropertyValue(0)
|
||||||
|
DownloadText = New PropertyValue(False)
|
||||||
|
DownloadTextPosts = New PropertyValue(False)
|
||||||
|
DownloadTextSpecialFolder = New PropertyValue(True)
|
||||||
UpdateResponserFile()
|
UpdateResponserFile()
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean,
|
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean,
|
||||||
@@ -138,7 +165,6 @@ Namespace API.Base
|
|||||||
Friend Overridable Sub BeginInit() Implements ISiteSettings.BeginInit
|
Friend Overridable Sub BeginInit() Implements ISiteSettings.BeginInit
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overridable Sub EndInit() Implements ISiteSettings.EndInit
|
Friend Overridable Sub EndInit() Implements ISiteSettings.EndInit
|
||||||
If _AllowUserAgentUpdate And Not DefaultUserAgent.IsEmptyString And Not Responser Is Nothing Then Responser.UserAgent = DefaultUserAgent
|
|
||||||
If CheckNetscapeCookiesOnEndInit Then Update_SaveCookiesNetscape(, True)
|
If CheckNetscapeCookiesOnEndInit Then Update_SaveCookiesNetscape(, True)
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -234,7 +260,7 @@ Namespace API.Base
|
|||||||
#Region "User info"
|
#Region "User info"
|
||||||
Protected UrlPatternUser As String = String.Empty
|
Protected UrlPatternUser As String = String.Empty
|
||||||
Friend Overridable Function GetUserUrl(ByVal User As IPluginContentProvider) As String Implements ISiteSettings.GetUserUrl
|
Friend Overridable Function GetUserUrl(ByVal User As IPluginContentProvider) As String Implements ISiteSettings.GetUserUrl
|
||||||
If Not UrlPatternUser.IsEmptyString Then Return String.Format(UrlPatternUser, User.Name)
|
If Not UrlPatternUser.IsEmptyString Then Return String.Format(UrlPatternUser, User.NameTrue.IfNullOrEmpty(User.Name))
|
||||||
Return String.Empty
|
Return String.Empty
|
||||||
End Function
|
End Function
|
||||||
Private Function ISiteSettings_GetUserPostUrl(ByVal User As IPluginContentProvider, ByVal Media As IUserMedia) As String Implements ISiteSettings.GetUserPostUrl
|
Private Function ISiteSettings_GetUserPostUrl(ByVal User As IPluginContentProvider, ByVal Media As IUserMedia) As String Implements ISiteSettings.GetUserPostUrl
|
||||||
@@ -371,11 +397,41 @@ Namespace API.Base
|
|||||||
End Sub
|
End Sub
|
||||||
Friend Overridable Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions
|
Friend Overridable Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions
|
||||||
If _UserOptionsExists Then
|
If _UserOptionsExists Then
|
||||||
If Options Is Nothing OrElse Not Options.GetType Is _UserOptionsType Then
|
If Options Is Nothing OrElse (Not Options.GetType Is _UserOptionsType OrElse Not UserOptionsValid(Options)) Then
|
||||||
Options = AConvert(Me, AModes.Var, _UserOptionsType,, True, Nothing)
|
Dim args% = 0
|
||||||
If Options Is Nothing Then Options = Activator.CreateInstance(_UserOptionsType)
|
Dim constructor As ConstructorInfo = Nothing
|
||||||
|
With _UserOptionsType.GetTypeInfo.DeclaredConstructors
|
||||||
|
If .ListExists Then
|
||||||
|
With .Where(Function(ByVal c As ConstructorInfo) As Boolean
|
||||||
|
With c.GetParameters
|
||||||
|
If .ListExists Then
|
||||||
|
If .Count = 1 Then
|
||||||
|
Return .Self()(0).ParameterType Is Me.GetType
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
End If
|
End If
|
||||||
If OpenForm Then
|
Else
|
||||||
|
Return True
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Return If(c.GetParameters?.Count, 0).ValueBetween(0, 1)
|
||||||
|
End Function)
|
||||||
|
If .ListExists Then
|
||||||
|
args = .Max(Of Integer)(Function(c) If(c.GetParameters?.Count, 0))
|
||||||
|
constructor = .First(Function(c) If(c.GetParameters?.Count, 0) = args)
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
If Not constructor Is Nothing Then
|
||||||
|
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)
|
||||||
|
If Not Options Is Nothing Then UserOptionsSetParameters(Options)
|
||||||
|
End If
|
||||||
|
If Not Options Is Nothing And OpenForm Then
|
||||||
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
|
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ Namespace API.Base
|
|||||||
Private Const Name_MediaPostID As String = "ID"
|
Private Const Name_MediaPostID As String = "ID"
|
||||||
Private Const Name_MediaPostDate As String = "Date"
|
Private Const Name_MediaPostDate As String = "Date"
|
||||||
Private Const Name_SpecialFolder As String = "SpecialFolder"
|
Private Const Name_SpecialFolder As String = "SpecialFolder"
|
||||||
|
Private Const Name_PostTextFile As String = "PostTextFile"
|
||||||
|
Private Const Name_PostTextFileSpecialFolder As String = "PostTextFileSpecialFolder"
|
||||||
#End Region
|
#End Region
|
||||||
Friend Enum Types As Integer
|
Friend Enum Types As Integer
|
||||||
Undefined = 0
|
Undefined = 0
|
||||||
@@ -46,12 +48,30 @@ Namespace API.Base
|
|||||||
End Enum
|
End Enum
|
||||||
Friend Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : Missing = 4 : End Enum
|
Friend Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : Missing = 4 : End Enum
|
||||||
Friend [Type] As Types
|
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 ReadOnly Property IsPhotoType As Boolean
|
||||||
|
Get
|
||||||
|
Return Type = Types.Picture Or Type = Types.GIF
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Friend URL_BASE As String
|
Friend URL_BASE As String
|
||||||
Friend URL As String
|
Friend URL As String
|
||||||
Friend MD5 As String
|
Friend MD5 As String
|
||||||
Friend [File] As SFile
|
Friend [File] As SFile
|
||||||
Friend Post As UserPost
|
Friend Post As UserPost
|
||||||
Friend PictureOption As String
|
Friend PictureOption As String
|
||||||
|
Friend PostText As String
|
||||||
|
Friend PostTextFile As SFile
|
||||||
|
Friend PostTextFileSpecialFolder As Boolean
|
||||||
Friend State As States
|
Friend State As States
|
||||||
Friend Attempts As Integer
|
Friend Attempts As Integer
|
||||||
''' <summary>
|
''' <summary>
|
||||||
@@ -125,6 +145,30 @@ Namespace API.Base
|
|||||||
Post = New UserPost(Post.ID, PostDate)
|
Post = New UserPost(Post.ID, PostDate)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
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
|
Private Property IUserMedia_SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||||
Get
|
Get
|
||||||
Return SpecialFolder
|
Return SpecialFolder
|
||||||
@@ -171,6 +215,9 @@ Namespace API.Base
|
|||||||
SpecialFolder = m.SpecialFolder
|
SpecialFolder = m.SpecialFolder
|
||||||
Attempts = m.Attempts
|
Attempts = m.Attempts
|
||||||
Me.Object = m.Object
|
Me.Object = m.Object
|
||||||
|
PostText = m.PostText
|
||||||
|
PostTextFile = m.PostTextFile
|
||||||
|
PostTextFileSpecialFolder = m.PostTextFileSpecialFolder
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal e As EContainer, ByVal UserInstance As IUserData)
|
Friend Sub New(ByVal e As EContainer, ByVal UserInstance As IUserData)
|
||||||
Type = e.Attribute(Name_MediaType).Value.FromXML(Of Integer)(CInt(Types.Undefined))
|
Type = e.Attribute(Name_MediaType).Value.FromXML(Of Integer)(CInt(Types.Undefined))
|
||||||
@@ -180,6 +227,8 @@ Namespace API.Base
|
|||||||
URL_BASE = e.Value
|
URL_BASE = e.Value
|
||||||
MD5 = e.Attribute(Name_MediaHash).Value
|
MD5 = e.Attribute(Name_MediaHash).Value
|
||||||
File = e.Attribute(Name_MediaFile).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 vp As Boolean? = Nothing
|
||||||
Dim upath$ = String.Empty
|
Dim upath$ = String.Empty
|
||||||
@@ -194,7 +243,13 @@ Namespace API.Base
|
|||||||
SpecialFolder = e.Attribute(Name_SpecialFolder).Value
|
SpecialFolder = e.Attribute(Name_SpecialFolder).Value
|
||||||
If Not SpecialFolder.IsEmptyString Then upath &= $"{SpecialFolder}\"
|
If Not SpecialFolder.IsEmptyString Then upath &= $"{SpecialFolder}\"
|
||||||
If vp.HasValue AndAlso vp.Value Then upath &= $"Video\"
|
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 {
|
Post = New UserPost With {
|
||||||
.ID = e.Attribute(Name_MediaPostID).Value,
|
.ID = e.Attribute(Name_MediaPostID).Value,
|
||||||
@@ -234,7 +289,9 @@ Namespace API.Base
|
|||||||
New EAttribute(Name_MediaURL, URL),
|
New EAttribute(Name_MediaURL, URL),
|
||||||
New EAttribute(Name_MediaHash, MD5),
|
New EAttribute(Name_MediaHash, MD5),
|
||||||
New EAttribute(Name_MediaFile, File.File),
|
New EAttribute(Name_MediaFile, File.File),
|
||||||
|
New EAttribute(Name_PostTextFile, PostTextFile.File),
|
||||||
New EAttribute(Name_SpecialFolder, SpecialFolder),
|
New EAttribute(Name_SpecialFolder, SpecialFolder),
|
||||||
|
New EAttribute(Name_PostTextFileSpecialFolder, PostTextFileSpecialFolder.BoolToInteger),
|
||||||
New EAttribute(Name_MediaPostID, Post.ID),
|
New EAttribute(Name_MediaPostID, Post.ID),
|
||||||
New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, DateTimeDefaultProvider, String.Empty))
|
New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, DateTimeDefaultProvider, String.Empty))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,21 @@ Namespace API.Base
|
|||||||
Friend Property TempPostsList As List(Of String)
|
Friend Property TempPostsList As List(Of String)
|
||||||
Protected ReadOnly Token As CancellationToken
|
Protected ReadOnly Token As CancellationToken
|
||||||
Friend Property DebugMode As Boolean = False
|
Friend Property DebugMode As Boolean = False
|
||||||
Friend Sub New(ByVal _Token As CancellationToken)
|
Friend Overridable Property MyWorkingDirectory As SFile = Nothing
|
||||||
|
Friend Sub New(ByVal _Token As CancellationToken, Optional ByVal _MainProcessName As String = Nothing, Optional ByVal WorkingDir As SFile = Nothing)
|
||||||
MyBase.New(True)
|
MyBase.New(True)
|
||||||
Token = _Token
|
Token = _Token
|
||||||
|
MainProcessName = _MainProcessName
|
||||||
|
If Not WorkingDir.IsEmptyString Then ChangeDirectory(WorkingDir)
|
||||||
End Sub
|
End Sub
|
||||||
|
Public Overrides Sub ChangeDirectory(ByVal Directory As SFile)
|
||||||
|
MyBase.ChangeDirectory(Directory)
|
||||||
|
If Not Directory.IsEmptyString Then MyWorkingDirectory = Directory
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Function Internal_Execute(ByVal Commands As IEnumerable(Of String), ByVal e As ErrorsDescriber) As Boolean
|
||||||
|
If Not Encoding.HasValue Then Encoding = UnicodeEncoding
|
||||||
|
Return MyBase.Internal_Execute(Commands, e)
|
||||||
|
End Function
|
||||||
Public Overrides Sub Create()
|
Public Overrides Sub Create()
|
||||||
If TempPostsList Is Nothing Then TempPostsList = New List(Of String)
|
If TempPostsList Is Nothing Then TempPostsList = New List(Of String)
|
||||||
MyBase.Create()
|
MyBase.Create()
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ Imports CookieUpdateModes = PersonalUtilities.Tools.Web.Cookies.CookieKeeper.Upd
|
|||||||
Namespace API.Base
|
Namespace API.Base
|
||||||
Friend MustInherit Class UserDataBase : Implements IUserData, IPluginContentProvider, IThrower
|
Friend MustInherit Class UserDataBase : Implements IUserData, IPluginContentProvider, IThrower
|
||||||
Friend Const UserFileAppender As String = "User"
|
Friend Const UserFileAppender As String = "User"
|
||||||
|
Friend Const PostTextSpecialFolderDefault As String = "txt"
|
||||||
#Region "Events"
|
#Region "Events"
|
||||||
Private ReadOnly UserUpdatedEventHandlers As List(Of IUserData.UserUpdatedEventHandler)
|
Private ReadOnly UserUpdatedEventHandlers As List(Of IUserData.UserUpdatedEventHandler)
|
||||||
Friend Custom Event UserUpdated As IUserData.UserUpdatedEventHandler Implements IUserData.UserUpdated
|
Friend Custom Event UserUpdated As IUserData.UserUpdatedEventHandler Implements IUserData.UserUpdated
|
||||||
@@ -80,6 +81,8 @@ Namespace API.Base
|
|||||||
Private _CollectionButtonsExists As Boolean = False
|
Private _CollectionButtonsExists As Boolean = False
|
||||||
Private _CollectionButtonsColorsSet As Boolean = False
|
Private _CollectionButtonsColorsSet As Boolean = False
|
||||||
Friend WithEvents BTT_CONTEXT_DOWN As ToolStripKeyMenuItem
|
Friend WithEvents BTT_CONTEXT_DOWN As ToolStripKeyMenuItem
|
||||||
|
Friend WithEvents BTT_CONTEXT_DOWN_LIMIT As ToolStripKeyMenuItem
|
||||||
|
Friend WithEvents BTT_CONTEXT_DOWN_DATE As ToolStripKeyMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_ERASE As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_ERASE As ToolStripMenuItem
|
||||||
@@ -98,6 +101,8 @@ Namespace API.Base
|
|||||||
End If
|
End If
|
||||||
End With
|
End With
|
||||||
BTT_CONTEXT_DOWN = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = Me}
|
BTT_CONTEXT_DOWN = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = Me}
|
||||||
|
BTT_CONTEXT_DOWN_LIMIT = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN_LIMIT"), .Tag = Me}
|
||||||
|
BTT_CONTEXT_DOWN_DATE = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN_DATE"), .Tag = Me}
|
||||||
BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = Me}
|
BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = Me}
|
||||||
BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = Me}
|
BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = Me}
|
||||||
BTT_CONTEXT_ERASE = New ToolStripMenuItem(tn, i) With {.Name = tnn("ERASE"), .Tag = Me}
|
BTT_CONTEXT_ERASE = New ToolStripMenuItem(tn, i) With {.Name = tnn("ERASE"), .Tag = Me}
|
||||||
@@ -117,7 +122,8 @@ Namespace API.Base
|
|||||||
cb = MyColor.EditBack
|
cb = MyColor.EditBack
|
||||||
cf = MyColor.EditFore
|
cf = MyColor.EditFore
|
||||||
End If
|
End If
|
||||||
For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_ERASE,
|
For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_DOWN_LIMIT, BTT_CONTEXT_DOWN_DATE,
|
||||||
|
BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_ERASE,
|
||||||
BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE}
|
BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE}
|
||||||
If Not b Is Nothing Then b.BackColor = cb : b.ForeColor = cf
|
If Not b Is Nothing Then b.BackColor = cb : b.ForeColor = cf
|
||||||
Next
|
Next
|
||||||
@@ -143,10 +149,13 @@ Namespace API.Base
|
|||||||
Protected Const Name_UserID As String = "UserID"
|
Protected Const Name_UserID As String = "UserID"
|
||||||
Protected Const Name_Options As String = "Options"
|
Protected Const Name_Options As String = "Options"
|
||||||
Protected Const Name_Description As String = "Description"
|
Protected Const Name_Description As String = "Description"
|
||||||
Private Const Name_ParseUserMediaOnly As String = "ParseUserMediaOnly"
|
Protected Const Name_ParseUserMediaOnly As String = "ParseUserMediaOnly"
|
||||||
Private Const Name_IsSubscription As String = UserInfo.Name_IsSubscription
|
Private Const Name_IsSubscription As String = UserInfo.Name_IsSubscription
|
||||||
Private Const Name_Temporary As String = "Temporary"
|
Private Const Name_Temporary As String = "Temporary"
|
||||||
Private Const Name_Favorite As String = "Favorite"
|
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_BackColor As String = "BackColor"
|
||||||
Private Const Name_ForeColor As String = "ForeColor"
|
Private Const Name_ForeColor As String = "ForeColor"
|
||||||
Private Const Name_CreatedByChannel As String = "CreatedByChannel"
|
Private Const Name_CreatedByChannel As String = "CreatedByChannel"
|
||||||
@@ -162,6 +171,7 @@ Namespace API.Base
|
|||||||
|
|
||||||
Private Const Name_VideoCount As String = "VideoCount"
|
Private Const Name_VideoCount As String = "VideoCount"
|
||||||
Private Const Name_PicturesCount As String = "PicturesCount"
|
Private Const Name_PicturesCount As String = "PicturesCount"
|
||||||
|
Private Const Name_TextCount As String = "TextCount"
|
||||||
Private Const Name_LastUpdated As String = "LastUpdated"
|
Private Const Name_LastUpdated As String = "LastUpdated"
|
||||||
|
|
||||||
Private Const Name_ScriptUse As String = "ScriptUse"
|
Private Const Name_ScriptUse As String = "ScriptUse"
|
||||||
@@ -173,6 +183,8 @@ Namespace API.Base
|
|||||||
#Region "Additional names"
|
#Region "Additional names"
|
||||||
Protected Const Name_SiteMode As String = "SiteMode"
|
Protected Const Name_SiteMode As String = "SiteMode"
|
||||||
Protected Const Name_TrueName As String = "TrueName"
|
Protected Const Name_TrueName As String = "TrueName"
|
||||||
|
'TODELETE Name_TrueName2
|
||||||
|
<Obsolete> Protected Const Name_TrueName2 As String = "NameTrue"
|
||||||
Protected Const Name_Arguments As String = "Arguments"
|
Protected Const Name_Arguments As String = "Arguments"
|
||||||
#End Region
|
#End Region
|
||||||
#End Region
|
#End Region
|
||||||
@@ -240,7 +252,20 @@ Namespace API.Base
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "User name, ID, exist, suspend, options"
|
#Region "User name, ID, exist, suspend, options"
|
||||||
Friend User As UserInfo
|
Friend User As UserInfo
|
||||||
|
Private _IsSavedPosts As Boolean = False
|
||||||
Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
|
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
|
Private _UserExists As Boolean = True
|
||||||
Friend Overridable Property UserExists As Boolean Implements IUserData.Exists, IPluginContentProvider.UserExists
|
Friend Overridable Property UserExists As Boolean Implements IUserData.Exists, IPluginContentProvider.UserExists
|
||||||
Get
|
Get
|
||||||
@@ -273,7 +298,31 @@ Namespace API.Base
|
|||||||
Return User.Name
|
Return User.Name
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
Friend Overridable Property ID As String = String.Empty Implements IUserData.ID, IPluginContentProvider.ID
|
Private _NameTrue As String = String.Empty
|
||||||
|
Friend Overridable Overloads Property NameTrue As String Implements IUserData.NameTrue, IPluginContentProvider.NameTrue
|
||||||
|
Get
|
||||||
|
Return NameTrue(False)
|
||||||
|
End Get
|
||||||
|
Set(ByVal NewName As String)
|
||||||
|
If Not _NameTrue = NewName Then EnvirChanged(NewName)
|
||||||
|
_NameTrue = NewName
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Friend Overloads ReadOnly Property NameTrue(ByVal Exact As Boolean) As String
|
||||||
|
Get
|
||||||
|
Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name))
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
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
|
Protected _FriendlyName As String = String.Empty
|
||||||
Friend Overridable Property FriendlyName As String Implements IUserData.FriendlyName
|
Friend Overridable Property FriendlyName As String Implements IUserData.FriendlyName
|
||||||
Get
|
Get
|
||||||
@@ -343,13 +392,21 @@ Namespace API.Base
|
|||||||
Protected Function UserDescriptionNeedToUpdate() As Boolean
|
Protected Function UserDescriptionNeedToUpdate() As Boolean
|
||||||
Return (UserDescription.IsEmptyString Or _DescriptionEveryTime) And Not _DescriptionChecked
|
Return (UserDescription.IsEmptyString Or _DescriptionEveryTime) And Not _DescriptionChecked
|
||||||
End Function
|
End Function
|
||||||
Protected Sub UserDescriptionUpdate(ByVal Descr As String)
|
Protected Sub UserDescriptionUpdate(ByVal Descr As String, Optional ByVal Force As Boolean = False,
|
||||||
If UserDescriptionNeedToUpdate() Then
|
Optional ByVal InsertFirst As Boolean = False, Optional ByVal AppendDate As Boolean = False)
|
||||||
|
If UserDescriptionNeedToUpdate() Or Force Then
|
||||||
|
If AppendDate Then Descr = $"{Now.ToStringDateDef}: {Descr}"
|
||||||
If UserDescription.IsEmptyString Then
|
If UserDescription.IsEmptyString Then
|
||||||
UserDescription = Descr
|
UserDescription = Descr
|
||||||
|
_ForceSaveUserInfo = True
|
||||||
ElseIf Not UserDescription.Contains(Descr) Then
|
ElseIf Not UserDescription.Contains(Descr) Then
|
||||||
|
If InsertFirst Then
|
||||||
|
UserDescription = $"{Descr}{vbNewLine}{UserDescription}"
|
||||||
|
Else
|
||||||
UserDescription &= $"{vbNewLine}----{vbNewLine}{Descr}"
|
UserDescription &= $"{vbNewLine}----{vbNewLine}{Descr}"
|
||||||
End If
|
End If
|
||||||
|
_ForceSaveUserInfo = True
|
||||||
|
End If
|
||||||
_DescriptionChecked = True
|
_DescriptionChecked = True
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
@@ -410,9 +467,7 @@ Namespace API.Base
|
|||||||
End Function
|
End Function
|
||||||
Friend Overridable Sub SetPicture(ByVal f As SFile) Implements IUserData.SetPicture
|
Friend Overridable Sub SetPicture(ByVal f As SFile) Implements IUserData.SetPicture
|
||||||
Try
|
Try
|
||||||
If f.Exists Then
|
If f.Exists Then UserImage.NewUserPicture(f, MyFile)
|
||||||
Using p As New UserImage(f, MyFile) : p.Save() : End Using
|
|
||||||
End If
|
|
||||||
Catch
|
Catch
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
@@ -451,11 +506,7 @@ BlockPictureScan:
|
|||||||
New ErrorsDescriber(EDP.ReturnValue) With {
|
New ErrorsDescriber(EDP.ReturnValue) With {
|
||||||
.ReturnValue = New List(Of SFile),
|
.ReturnValue = New List(Of SFile),
|
||||||
.ReturnValueExists = True}).FirstOrDefault
|
.ReturnValueExists = True}).FirstOrDefault
|
||||||
If NewPicFile.Exists Then
|
If NewPicFile.Exists Then p = UserImage.NewUserPicture(NewPicFile, MyFile,, True) : GoTo BlockReturn
|
||||||
p = New UserImage(NewPicFile, MyFile)
|
|
||||||
p.Save()
|
|
||||||
GoTo BlockReturn
|
|
||||||
End If
|
|
||||||
BlockDeletePictureFolder:
|
BlockDeletePictureFolder:
|
||||||
On Error GoTo BlockReturn
|
On Error GoTo BlockReturn
|
||||||
If DelPath Then
|
If DelPath Then
|
||||||
@@ -615,6 +666,9 @@ BlockNullPicture:
|
|||||||
Friend Overridable Property ReadyForDownload As Boolean = True Implements IUserData.ReadyForDownload
|
Friend Overridable Property ReadyForDownload As Boolean = True Implements IUserData.ReadyForDownload
|
||||||
Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages
|
Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages
|
||||||
Friend Property DownloadVideos As Boolean = True Implements IUserData.DownloadVideos
|
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
|
Friend Property DownloadMissingOnly As Boolean = False Implements IUserData.DownloadMissingOnly
|
||||||
Private _IconBannerDownloaded As Boolean = False
|
Private _IconBannerDownloaded As Boolean = False
|
||||||
Friend WriteOnly Property IconBannerDownloaded As Boolean
|
Friend WriteOnly Property IconBannerDownloaded As Boolean
|
||||||
@@ -654,6 +708,7 @@ BlockNullPicture:
|
|||||||
End Sub
|
End Sub
|
||||||
Protected ReadOnly _TempMediaList As List(Of UserMedia)
|
Protected ReadOnly _TempMediaList As List(Of UserMedia)
|
||||||
Protected ReadOnly _TempPostsList As List(Of String)
|
Protected ReadOnly _TempPostsList As List(Of String)
|
||||||
|
Private ReadOnly _MD5List As List(Of String)
|
||||||
Friend Function GetLastImageAddress() As SFile
|
Friend Function GetLastImageAddress() As SFile
|
||||||
If _ContentList.Count > 0 Then
|
If _ContentList.Count > 0 Then
|
||||||
Return _ContentList.LastOrDefault(Function(c) c.Type = UTypes.Picture And Not c.File.IsEmptyString And Not c.File.Extension = "gif").File
|
Return _ContentList.LastOrDefault(Function(c) c.Type = UTypes.Picture And Not c.File.IsEmptyString And Not c.File.Extension = "gif").File
|
||||||
@@ -679,6 +734,7 @@ BlockNullPicture:
|
|||||||
Protected MyFileSettings As SFile
|
Protected MyFileSettings As SFile
|
||||||
Protected MyFileData As SFile
|
Protected MyFileData As SFile
|
||||||
Protected MyFilePosts As SFile
|
Protected MyFilePosts As SFile
|
||||||
|
Private MyMD5File As SFile
|
||||||
Friend Overridable Property FileExists As Boolean = False Implements IUserData.FileExists
|
Friend Overridable Property FileExists As Boolean = False Implements IUserData.FileExists
|
||||||
Friend Overridable Property DataMerging As Boolean
|
Friend Overridable Property DataMerging As Boolean
|
||||||
Get
|
Get
|
||||||
@@ -724,9 +780,23 @@ BlockNullPicture:
|
|||||||
End If
|
End If
|
||||||
End Set
|
End Set
|
||||||
End Property
|
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
|
Friend Overridable ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer Implements IUserData.DownloadedTotal
|
||||||
Get
|
Get
|
||||||
Return DownloadedPictures(Total) + DownloadedVideos(Total)
|
Return DownloadedPictures(Total) + DownloadedVideos(Total) + DownloadedTexts(Total)
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
Friend ReadOnly Property DownloadedInformation As String Implements IUserData.DownloadedInformation
|
Friend ReadOnly Property DownloadedInformation As String Implements IUserData.DownloadedInformation
|
||||||
@@ -856,6 +926,7 @@ BlockNullPicture:
|
|||||||
LatestData = New List(Of UserMedia)
|
LatestData = New List(Of UserMedia)
|
||||||
_TempMediaList = New List(Of UserMedia)
|
_TempMediaList = New List(Of UserMedia)
|
||||||
_TempPostsList = New List(Of String)
|
_TempPostsList = New List(Of String)
|
||||||
|
_MD5List = New List(Of String)
|
||||||
Labels = New List(Of String)
|
Labels = New List(Of String)
|
||||||
UserUpdatedEventHandlers = New List(Of IUserData.UserUpdatedEventHandler)
|
UserUpdatedEventHandlers = New List(Of IUserData.UserUpdatedEventHandler)
|
||||||
UserDownloadStateChangedEventHandlers = New List(Of UserDownloadStateChangedEventHandler)
|
UserDownloadStateChangedEventHandlers = New List(Of UserDownloadStateChangedEventHandler)
|
||||||
@@ -905,6 +976,10 @@ BlockNullPicture:
|
|||||||
FileExists = True
|
FileExists = True
|
||||||
Using x As New XmlFile(MyFileSettings) With {.XmlReadOnly = True}
|
Using x As New XmlFile(MyFileSettings) With {.XmlReadOnly = True}
|
||||||
If User.Name.IsEmptyString Then User.Name = x.Value(Name_UserName)
|
If User.Name.IsEmptyString Then User.Name = x.Value(Name_UserName)
|
||||||
|
_NameTrue = x.Value(Name_TrueName)
|
||||||
|
#Disable Warning BC40008
|
||||||
|
If _NameTrue.IsEmptyString AndAlso x.Contains(Name_TrueName2) Then _NameTrue = x.Value(Name_TrueName2)
|
||||||
|
#Enable Warning
|
||||||
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
|
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
|
||||||
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
|
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
|
||||||
ID = x.Value(Name_UserID)
|
ID = x.Value(Name_UserID)
|
||||||
@@ -932,9 +1007,13 @@ BlockNullPicture:
|
|||||||
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
||||||
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
||||||
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
||||||
|
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)
|
_IconBannerDownloaded = x.Value(Name_IconBannerDownloaded).FromXML(Of Boolean)(False)
|
||||||
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
||||||
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
||||||
|
DownloadedTexts(True) = x.Value(Name_TextCount).FromXML(Of Integer)(0)
|
||||||
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
||||||
ScriptUse = x.Value(Name_ScriptUse).FromXML(Of Boolean)(False)
|
ScriptUse = x.Value(Name_ScriptUse).FromXML(Of Boolean)(False)
|
||||||
ScriptData = x.Value(Name_ScriptData)
|
ScriptData = x.Value(Name_ScriptData)
|
||||||
@@ -950,7 +1029,13 @@ BlockNullPicture:
|
|||||||
LogError(ex, "user information loading error")
|
LogError(ex, "user information loading error")
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overridable Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation
|
Private Sub UpdateUserInformation_Ex()
|
||||||
|
If _ForceSaveUserInfoOnException Then UpdateUserInformation()
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Overloads Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation
|
||||||
|
UpdateUserInformation(False)
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Overloads Sub UpdateUserInformation(ByVal DisableUserInfoUpdate As Boolean)
|
||||||
Try
|
Try
|
||||||
UpdateDataFiles()
|
UpdateDataFiles()
|
||||||
MyFileSettings.Exists(SFO.Path)
|
MyFileSettings.Exists(SFO.Path)
|
||||||
@@ -959,6 +1044,7 @@ BlockNullPicture:
|
|||||||
x.Add(Name_Plugin, HOST.Key)
|
x.Add(Name_Plugin, HOST.Key)
|
||||||
x.Add(Name_AccountName, AccountName)
|
x.Add(Name_AccountName, AccountName)
|
||||||
x.Add(Name_UserName, User.Name)
|
x.Add(Name_UserName, User.Name)
|
||||||
|
x.Add(Name_TrueName, _NameTrue)
|
||||||
x.Add(Name_Model_User, CInt(UserModel))
|
x.Add(Name_Model_User, CInt(UserModel))
|
||||||
x.Add(Name_Model_Collection, CInt(CollectionModel))
|
x.Add(Name_Model_Collection, CInt(CollectionModel))
|
||||||
x.Add(Name_SpecialPath, User.SpecialPath)
|
x.Add(Name_SpecialPath, User.SpecialPath)
|
||||||
@@ -987,9 +1073,13 @@ BlockNullPicture:
|
|||||||
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
||||||
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
||||||
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
||||||
|
x.Add(Name_DownloadText, DownloadText.BoolToInteger)
|
||||||
|
x.Add(Name_DownloadTextPosts, DownloadTextPosts.BoolToInteger)
|
||||||
|
x.Add(Name_DownloadTextSpecialFolder, DownloadTextSpecialFolder.BoolToInteger)
|
||||||
x.Add(Name_IconBannerDownloaded, _IconBannerDownloaded.BoolToInteger)
|
x.Add(Name_IconBannerDownloaded, _IconBannerDownloaded.BoolToInteger)
|
||||||
x.Add(Name_VideoCount, DownloadedVideos(True))
|
x.Add(Name_VideoCount, DownloadedVideos(True))
|
||||||
x.Add(Name_PicturesCount, DownloadedPictures(True))
|
x.Add(Name_PicturesCount, DownloadedPictures(True))
|
||||||
|
x.Add(Name_TextCount, DownloadedTexts(True))
|
||||||
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
||||||
x.Add(Name_ScriptUse, ScriptUse.BoolToInteger)
|
x.Add(Name_ScriptUse, ScriptUse.BoolToInteger)
|
||||||
x.Add(Name_ScriptData, ScriptData)
|
x.Add(Name_ScriptData, ScriptData)
|
||||||
@@ -1001,7 +1091,7 @@ BlockNullPicture:
|
|||||||
|
|
||||||
x.Save(MyFileSettings)
|
x.Save(MyFileSettings)
|
||||||
End Using
|
End Using
|
||||||
If Not IsSavedPosts Then Settings.UpdateUsersList(User, True)
|
If Not IsSavedPosts And Not DisableUserInfoUpdate Then Settings.UpdateUsersList(User, True)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LogError(ex, "user information saving error")
|
LogError(ex, "user information saving error")
|
||||||
End Try
|
End Try
|
||||||
@@ -1034,6 +1124,8 @@ BlockNullPicture:
|
|||||||
If _ContentList.Count > 0 Then x.AddRange(_ContentList)
|
If _ContentList.Count > 0 Then x.AddRange(_ContentList)
|
||||||
x.Save(MyFileData)
|
x.Save(MyFileData)
|
||||||
End Using
|
End Using
|
||||||
|
If Not MyMD5File.IsEmptyString And _MD5List.Count > 0 Then _
|
||||||
|
TextSaver.SaveTextToFile(_MD5List.ListToString(Environment.NewLine), MyMD5File, True,, EDP.None)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LogError(ex, "history saving error")
|
LogError(ex, "history saving error")
|
||||||
End Try
|
End Try
|
||||||
@@ -1115,6 +1207,7 @@ BlockNullPicture:
|
|||||||
Protected UseClientTokens As Boolean = False
|
Protected UseClientTokens As Boolean = False
|
||||||
Protected _ForceSaveUserData As Boolean = False
|
Protected _ForceSaveUserData As Boolean = False
|
||||||
Protected _ForceSaveUserInfo As Boolean = False
|
Protected _ForceSaveUserInfo As Boolean = False
|
||||||
|
Protected _ForceSaveUserInfoOnException As Boolean = False
|
||||||
Private _DownloadInProgress As Boolean = False
|
Private _DownloadInProgress As Boolean = False
|
||||||
Private _EnvirUserExists As Boolean
|
Private _EnvirUserExists As Boolean
|
||||||
Private _EnvirUserSuspended As Boolean
|
Private _EnvirUserSuspended As Boolean
|
||||||
@@ -1128,11 +1221,13 @@ BlockNullPicture:
|
|||||||
TokenPersonal = Nothing
|
TokenPersonal = Nothing
|
||||||
ProgressPre.Reset()
|
ProgressPre.Reset()
|
||||||
UpdateDataFiles()
|
UpdateDataFiles()
|
||||||
|
_MD5Loaded = False
|
||||||
_DownloadInProgress = True
|
_DownloadInProgress = True
|
||||||
_DescriptionChecked = False
|
_DescriptionChecked = False
|
||||||
_DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime
|
_DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime
|
||||||
_ForceSaveUserData = False
|
_ForceSaveUserData = False
|
||||||
_ForceSaveUserInfo = False
|
_ForceSaveUserInfo = False
|
||||||
|
_ForceSaveUserInfoOnException = False
|
||||||
_EnvirUserExists = UserExists
|
_EnvirUserExists = UserExists
|
||||||
_EnvirUserSuspended = UserSuspended
|
_EnvirUserSuspended = UserSuspended
|
||||||
_EnvirCreatedByChannel = CreatedByChannel
|
_EnvirCreatedByChannel = CreatedByChannel
|
||||||
@@ -1149,6 +1244,8 @@ BlockNullPicture:
|
|||||||
Select Case Caller
|
Select Case Caller
|
||||||
Case NameOf(UserExists) : If Not _EnvirUserExists = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
|
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(UserSuspended) : If Not _EnvirUserSuspended = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
|
||||||
|
Case NameOf(NameTrue) : _EnvirChanged = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
|
||||||
|
Case NameOf(ID) : _EnvirChanged = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
|
||||||
Case Else : _EnvirChanged = True
|
Case Else : _EnvirChanged = True
|
||||||
End Select
|
End Select
|
||||||
End If
|
End If
|
||||||
@@ -1202,6 +1299,7 @@ BlockNullPicture:
|
|||||||
If Not DownloadImages Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.GIF Or m.Type = UTypes.Picture)
|
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
|
If Not DownloadVideos Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.Video Or
|
||||||
m.Type = UTypes.VideoPre Or m.Type = UTypes.m3u8)
|
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)
|
If DownloadMissingOnly Then _TempMediaList.RemoveAll(Function(m) Not m.State = UStates.Missing)
|
||||||
End If
|
End If
|
||||||
|
|
||||||
@@ -1209,7 +1307,7 @@ BlockNullPicture:
|
|||||||
ProgressPre.Done()
|
ProgressPre.Done()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
|
|
||||||
If UseMD5Comparison And Not IsSubscription Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token)
|
If RemoveExistingDuplicates And Not IsSubscription Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token)
|
||||||
|
|
||||||
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And Not __isChannelsSupport Then
|
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And Not __isChannelsSupport Then
|
||||||
If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd)
|
If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd)
|
||||||
@@ -1262,21 +1360,26 @@ BlockNullPicture:
|
|||||||
ThrowIfDisposed()
|
ThrowIfDisposed()
|
||||||
If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated()
|
If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated()
|
||||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested Or TokenPersonal.IsCancellationRequested Or TokenQueue.IsCancellationRequested
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested Or TokenPersonal.IsCancellationRequested Or TokenQueue.IsCancellationRequested
|
||||||
|
UpdateUserInformation_Ex()
|
||||||
MyMainLOG = $"{ToStringForLog()}: downloading canceled"
|
MyMainLOG = $"{ToStringForLog()}: downloading canceled"
|
||||||
Canceled = True
|
Canceled = True
|
||||||
Catch exit_ex As ExitException
|
Catch exit_ex As ExitException
|
||||||
|
UpdateUserInformation_Ex()
|
||||||
If Not exit_ex.Silent Then
|
If Not exit_ex.Silent Then
|
||||||
If exit_ex.SimpleLogLine Then
|
If exit_ex.SimpleLogLine Then
|
||||||
MyMainLOG = $"{ToStringForLog()}: downloading interrupted (exit) ({exit_ex.Message})"
|
LogError(Nothing, $"downloading interrupted (exit) ({exit_ex.Message})")
|
||||||
Else
|
Else
|
||||||
ErrorsDescriber.Execute(EDP.SendToLog, exit_ex, $"{ToStringForLog()}: downloading interrupted (exit)")
|
LogError(exit_ex, "downloading interrupted (exit)")
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
If _EnvirInvokeUserUpdated Then OnUserUpdated()
|
||||||
Canceled = True
|
Canceled = True
|
||||||
Catch dex As ObjectDisposedException When Disposed
|
Catch dex As ObjectDisposedException When Disposed
|
||||||
Canceled = True
|
Canceled = True
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
UpdateUserInformation_Ex()
|
||||||
LogError(ex, "downloading data error")
|
LogError(ex, "downloading data error")
|
||||||
|
If _EnvirInvokeUserUpdated Then OnUserUpdated()
|
||||||
HasError = True
|
HasError = True
|
||||||
Finally
|
Finally
|
||||||
If Not UserExists Then AddNonExistingUserToLog($"User '{ToStringForLog()}' not found on the site")
|
If Not UserExists Then AddNonExistingUserToLog($"User '{ToStringForLog()}' not found on the site")
|
||||||
@@ -1312,6 +1415,11 @@ BlockNullPicture:
|
|||||||
MyFilePosts = MyFileSettings
|
MyFilePosts = MyFileSettings
|
||||||
MyFilePosts.Name &= "_Posts"
|
MyFilePosts.Name &= "_Posts"
|
||||||
MyFilePosts.Extension = "txt"
|
MyFilePosts.Extension = "txt"
|
||||||
|
If Not IsSavedPosts Then
|
||||||
|
MyMD5File = MyFileSettings
|
||||||
|
MyMD5File.Name &= "_MD5"
|
||||||
|
MyMD5File.Extension = "txt"
|
||||||
|
End If
|
||||||
Else
|
Else
|
||||||
Throw New ArgumentNullException("User.File", "User file not detected")
|
Throw New ArgumentNullException("User.File", "User file not detected")
|
||||||
End If
|
End If
|
||||||
@@ -1331,6 +1439,16 @@ BlockNullPicture:
|
|||||||
Cache.Validate()
|
Cache.Validate()
|
||||||
Return Cache
|
Return Cache
|
||||||
End Function
|
End Function
|
||||||
|
#Region "GDL File Names"
|
||||||
|
Protected GDLFileNameProvider As ANumbers = Nothing
|
||||||
|
Protected Sub GDLResetFileNameProvider(Optional ByVal GroupSize As Integer? = Nothing)
|
||||||
|
GDLFileNameProvider = New ANumbers With {.FormatOptions = ANumbers.Options.FormatNumberGroup + ANumbers.Options.Groups}
|
||||||
|
GDLFileNameProvider.GroupSize = If(GroupSize, 3)
|
||||||
|
End Sub
|
||||||
|
Protected Function GDLRenameFile(ByVal Input As SFile, ByVal i As Integer) As SFile
|
||||||
|
Return SFile.Rename(Input, $"{Input.PathWithSeparator}{i.NumToString(GDLFileNameProvider)}.{Input.Extension}",, EDP.ThrowException)
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
#Region "DownloadSingleObject"
|
#Region "DownloadSingleObject"
|
||||||
Protected IsSingleObjectDownload As Boolean = False
|
Protected IsSingleObjectDownload As Boolean = False
|
||||||
Friend Overridable Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken) Implements IUserData.DownloadSingleObject
|
Friend Overridable Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken) Implements IUserData.DownloadSingleObject
|
||||||
@@ -1407,6 +1525,7 @@ BlockNullPicture:
|
|||||||
Data.DownloadState = UserMediaStates.Missing
|
Data.DownloadState = UserMediaStates.Missing
|
||||||
End If
|
End If
|
||||||
YouTube.Objects.YouTubeMediaContainerBase.Update(_ContentNew(0), Data)
|
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
|
If ResetTitle And Not _ContentNew(0).File.Name.IsEmptyString Then Data.Title = _ContentNew(0).File.Name
|
||||||
Else
|
Else
|
||||||
Data.DownloadState = UserMediaStates.Missing
|
Data.DownloadState = UserMediaStates.Missing
|
||||||
@@ -1435,23 +1554,25 @@ BlockNullPicture:
|
|||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "MD5 support"
|
#Region "MD5 support"
|
||||||
Protected Const VALIDATE_MD5_ERROR As String = "VALIDATE_MD5_ERROR"
|
Private Const VALIDATE_MD5_ERROR As String = "VALIDATE_MD5_ERROR"
|
||||||
Friend Property UseMD5Comparison As Boolean = False
|
Friend Property UseMD5Comparison As Boolean = False
|
||||||
Protected Property StartMD5Checked As Boolean = False
|
Protected Property StartMD5Checked As Boolean = False
|
||||||
Friend Property RemoveExistingDuplicates As Boolean = False
|
Friend Property RemoveExistingDuplicates As Boolean = False
|
||||||
Protected Overridable Sub ValidateMD5(ByVal Token As CancellationToken)
|
Private ReadOnly ErrMD5 As New ErrorsDescriber(EDP.ReturnValue)
|
||||||
|
Private _MD5Loaded As Boolean = False
|
||||||
|
Private Sub LoadMD5()
|
||||||
Try
|
Try
|
||||||
Dim missingMD5 As Predicate(Of UserMedia) = Function(d) (d.Type = UTypes.GIF Or d.Type = UTypes.Picture) And d.MD5.IsEmptyString
|
If Not _MD5Loaded Then
|
||||||
If UseMD5Comparison And _TempMediaList.Exists(missingMD5) Then
|
_MD5Loaded = True
|
||||||
Dim i%
|
_MD5List.Clear()
|
||||||
Dim itemsCount% = 0
|
If _ContentList.Count > 0 Then _MD5List.ListAddList(_ContentList.Select(Function(c) c.MD5), LAP.NotContainsOnly, EDP.ReturnValue)
|
||||||
Dim limit% = If(DownloadTopCount, 0)
|
If MyMD5File.Exists Then _MD5List.ListAddList(MyMD5File.GetLines, LAP.NotContainsOnly, EDP.ThrowException)
|
||||||
Dim data As UserMedia = Nothing
|
End If
|
||||||
Dim hashList As New Dictionary(Of String, SFile)
|
Catch ex As Exception
|
||||||
Dim f As SFile
|
ErrorsDescriber.Execute(EDP.SendToLog, ex, "LoadMD5")
|
||||||
Dim ErrMD5 As New ErrorsDescriber(EDP.ReturnValue)
|
End Try
|
||||||
Dim __getMD5 As Func(Of UserMedia, Boolean, String) =
|
End Sub
|
||||||
Function(ByVal __data As UserMedia, ByVal IsUrl As Boolean) As String
|
Private Function ValidateMD5_GetMD5(ByVal __data As UserMedia, ByVal IsUrl As Boolean) As String
|
||||||
Try
|
Try
|
||||||
Dim ImgFormat As Imaging.ImageFormat = Nothing
|
Dim ImgFormat As Imaging.ImageFormat = Nothing
|
||||||
Dim hash$ = String.Empty
|
Dim hash$ = String.Empty
|
||||||
@@ -1483,33 +1604,44 @@ BlockNullPicture:
|
|||||||
Return String.Empty
|
Return String.Empty
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
If Not StartMD5Checked Then
|
Private Sub ValidateMD5(ByVal Token As CancellationToken)
|
||||||
StartMD5Checked = True
|
Try
|
||||||
If _ContentList.Exists(missingMD5) Then
|
Dim missingMD5 As Predicate(Of UserMedia) = Function(d) (d.Type = UTypes.GIF Or d.Type = UTypes.Picture) And d.MD5.IsEmptyString
|
||||||
Dim existingFiles As List(Of SFile) = SFile.GetFiles(MyFileSettings.CutPath, "*.jpg|*.jpeg|*.png|*.gif",, EDP.ReturnValue).ListIfNothing
|
|
||||||
Dim eIndx%
|
|
||||||
Dim eFinder As Predicate(Of SFile) = Function(ff) ff.File = data.File.File
|
|
||||||
If RemoveExistingDuplicates Then
|
If RemoveExistingDuplicates Then
|
||||||
RemoveExistingDuplicates = False
|
RemoveExistingDuplicates = False
|
||||||
_ForceSaveUserInfo = True
|
_ForceSaveUserInfo = True
|
||||||
|
LoadMD5()
|
||||||
|
Dim i%
|
||||||
|
Dim itemsCount% = 0
|
||||||
|
Dim limit% = If(DownloadTopCount, 0)
|
||||||
|
Dim data As UserMedia = Nothing
|
||||||
|
Dim f As SFile
|
||||||
|
|
||||||
|
If Not StartMD5Checked Then
|
||||||
|
StartMD5Checked = True
|
||||||
|
Dim existingFiles As List(Of SFile) = SFile.GetFiles(MyFileSettings.CutPath, "*.jpg|*.jpeg|*.png|*.gif",, EDP.ReturnValue).ListIfNothing
|
||||||
|
Dim eIndx%
|
||||||
|
Dim eFinder As Predicate(Of SFile) = Function(ff) ff.File = data.File.File
|
||||||
|
|
||||||
If existingFiles.Count > 0 Then
|
If existingFiles.Count > 0 Then
|
||||||
Dim h$
|
Dim h$
|
||||||
ProgressPre.ChangeMax(existingFiles.Count)
|
ProgressPre.ChangeMax(existingFiles.Count)
|
||||||
For i = existingFiles.Count - 1 To 0 Step -1
|
For i = existingFiles.Count - 1 To 0 Step -1
|
||||||
ProgressPre.Perform()
|
ProgressPre.Perform()
|
||||||
h = __getMD5(New UserMedia With {.File = existingFiles(i)}, False)
|
h = ValidateMD5_GetMD5(New UserMedia With {.File = existingFiles(i)}, False)
|
||||||
If Not h.IsEmptyString Then
|
If Not h.IsEmptyString Then
|
||||||
If hashList.ContainsKey(h) Then
|
If _MD5List.Contains(h) Then
|
||||||
MyMainLOG = $"{ToStringForLog()}: Removed image [{existingFiles(i).File}] (duplicate of [{hashList(h).File}])"
|
MyMainLOG = $"{ToStringForLog()}: Removed image [{existingFiles(i).File}] (duplicate)"
|
||||||
existingFiles(i).Delete(SFO.File, SFODelete.DeleteToRecycleBin, ErrMD5)
|
existingFiles(i).Delete(SFO.File, SFODelete.DeleteToRecycleBin, ErrMD5)
|
||||||
existingFiles.RemoveAt(i)
|
existingFiles.RemoveAt(i)
|
||||||
Else
|
Else
|
||||||
hashList.Add(h, existingFiles(i))
|
_MD5List.Add(h)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End If
|
|
||||||
|
If _ContentList.Count > 0 AndAlso _ContentList.Exists(missingMD5) Then
|
||||||
ProgressPre.ChangeMax(_ContentList.Count)
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
For i = 0 To _ContentList.Count - 1
|
For i = 0 To _ContentList.Count - 1
|
||||||
data = _ContentList(i)
|
data = _ContentList(i)
|
||||||
@@ -1519,13 +1651,15 @@ BlockNullPicture:
|
|||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
eIndx = existingFiles.FindIndex(eFinder)
|
eIndx = existingFiles.FindIndex(eFinder)
|
||||||
If eIndx >= 0 Then
|
If eIndx >= 0 Then
|
||||||
data.MD5 = __getMD5(New UserMedia With {.File = existingFiles(eIndx)}, False)
|
data.MD5 = ValidateMD5_GetMD5(New UserMedia With {.File = existingFiles(eIndx)}, False)
|
||||||
If Not data.MD5.IsEmptyString Then _ContentList(i) = data : _ForceSaveUserData = True
|
If Not data.MD5.IsEmptyString Then _ContentList(i) = data : _ForceSaveUserData = True
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
existingFiles.RemoveAll(eFinder)
|
existingFiles.RemoveAll(eFinder)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
End If
|
||||||
|
|
||||||
If existingFiles.Count > 0 Then
|
If existingFiles.Count > 0 Then
|
||||||
ProgressPre.ChangeMax(existingFiles.Count)
|
ProgressPre.ChangeMax(existingFiles.Count)
|
||||||
For i = 0 To existingFiles.Count - 1
|
For i = 0 To existingFiles.Count - 1
|
||||||
@@ -1537,43 +1671,14 @@ BlockNullPicture:
|
|||||||
.File = f
|
.File = f
|
||||||
}
|
}
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
data.MD5 = __getMD5(data, False)
|
data.MD5 = ValidateMD5_GetMD5(data, False)
|
||||||
If Not data.MD5.IsEmptyString Then _ContentList.Add(data) : _ForceSaveUserData = True
|
If Not data.MD5.IsEmptyString Then _ContentList.Add(data) : _ForceSaveUserData = True
|
||||||
Next
|
Next
|
||||||
existingFiles.Clear()
|
existingFiles.Clear()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
|
||||||
|
|
||||||
If _ContentList.Count > 0 Then
|
If _ContentList.Count > 0 Then _MD5List.ListAddList(_ContentList.Select(Function(d) d.MD5), LAP.NotContainsOnly, EDP.ReturnValue)
|
||||||
With _ContentList.Select(Function(d) d.MD5)
|
|
||||||
If .ListExists Then .ToList.ForEach(Sub(md5value) _
|
|
||||||
If Not md5value.IsEmptyString AndAlso Not hashList.ContainsKey(md5value) Then hashList.Add(md5value, New SFile))
|
|
||||||
End With
|
|
||||||
End If
|
|
||||||
|
|
||||||
ProgressPre.ChangeMax(_TempMediaList.Count)
|
|
||||||
For i = _TempMediaList.Count - 1 To 0 Step -1
|
|
||||||
ProgressPre.Perform()
|
|
||||||
If limit > 0 And itemsCount >= limit Then
|
|
||||||
_TempMediaList.RemoveAt(i)
|
|
||||||
Else
|
|
||||||
data = _TempMediaList(i)
|
|
||||||
If missingMD5(data) Then
|
|
||||||
ThrowAny(Token)
|
|
||||||
data.MD5 = __getMD5(data, True)
|
|
||||||
If Not data.MD5.IsEmptyString Then
|
|
||||||
If hashList.ContainsKey(data.MD5) Then
|
|
||||||
_TempMediaList.RemoveAt(i)
|
|
||||||
Else
|
|
||||||
hashList.Add(data.MD5, New SFile)
|
|
||||||
_TempMediaList(i) = data
|
|
||||||
itemsCount += 1
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
End If
|
End If
|
||||||
Catch iex As ArgumentOutOfRangeException When Disposed
|
Catch iex As ArgumentOutOfRangeException When Disposed
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -1611,22 +1716,27 @@ BlockNullPicture:
|
|||||||
Source.Progress.Done()
|
Source.Progress.Done()
|
||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
|
Protected Const VideoFolderName As String = "Video"
|
||||||
Protected Sub DownloadContentDefault(ByVal Token As CancellationToken)
|
Protected Sub DownloadContentDefault(ByVal Token As CancellationToken)
|
||||||
Try
|
Try
|
||||||
Dim i%
|
Dim i%
|
||||||
Dim dCount% = 0, dTotal% = 0
|
Dim dCount% = 0, dTotal% = 0
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If _ContentNew.Count > 0 Then
|
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 _ContentNew.Count > 0 Then
|
||||||
|
If UseMD5Comparison Then LoadMD5()
|
||||||
MyFile.Exists(SFO.Path)
|
MyFile.Exists(SFO.Path)
|
||||||
Dim MissingErrorsAdd As Boolean = Settings.AddMissingErrorsToLog
|
Dim MissingErrorsAdd As Boolean = Settings.AddMissingErrorsToLog
|
||||||
Dim MyDir$ = DownloadContentDefault_GetRootDir()
|
Dim MyDir$ = DownloadContentDefault_GetRootDir()
|
||||||
Dim vsf As Boolean = SeparateVideoFolderF
|
Dim vsf As Boolean = SeparateVideoFolderF
|
||||||
Dim __isVideo As Boolean
|
Dim __isVideo As Boolean
|
||||||
Dim __interrupt 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 v As UserMedia
|
||||||
|
Dim __fileDeleted As Boolean
|
||||||
Dim fileNumProvider As SFileNumbers = SFileNumbers.Default
|
Dim fileNumProvider As SFileNumbers = SFileNumbers.Default
|
||||||
Dim __deleteFile As Action(Of SFile, String) = Sub(ByVal FileToDelete As SFile, ByVal FileUrl As String)
|
Dim __deleteFile As Action(Of SFile, String) = Sub(ByVal FileToDelete As SFile, ByVal FileUrl As String)
|
||||||
Try
|
Try
|
||||||
@@ -1638,9 +1748,23 @@ BlockNullPicture:
|
|||||||
ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex)
|
ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
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)
|
Using w As New OptionalWebClient(Me)
|
||||||
If vsf Then CSFileP($"{MyDir}\Video\").Exists(SFO.Path)
|
If vsf Then CSFileP($"{MyDir}\{VideoFolderName}\").Exists(SFO.Path)
|
||||||
Progress.Maximum += _ContentNew.Count
|
Progress.Maximum += _ContentNew.Count
|
||||||
If IsSingleObjectDownload Then
|
If IsSingleObjectDownload Then
|
||||||
If _ContentNew.Count = 1 And _ContentNew(0).Type = UTypes.Video Then
|
If _ContentNew.Count = 1 And _ContentNew(0).Type = UTypes.Video Then
|
||||||
@@ -1668,8 +1792,12 @@ BlockNullPicture:
|
|||||||
|
|
||||||
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
||||||
|
|
||||||
If Not f.IsEmptyString And Not v.URL.IsEmptyString Then
|
__fileDeleted = False
|
||||||
|
postProcessWebp = False
|
||||||
|
|
||||||
|
If (v.Type = UTypes.Text And DownloadText) Or (Not f.IsEmptyString And Not v.URL.IsEmptyString) Then
|
||||||
Try
|
Try
|
||||||
|
If v.Type = UTypes.Text Then GoTo stxt
|
||||||
__isVideo = v.Type = UTypes.Video Or f.Extension = "mp4" Or v.Type = UTypes.m3u8
|
__isVideo = v.Type = UTypes.Video Or f.Extension = "mp4" Or v.Type = UTypes.m3u8
|
||||||
|
|
||||||
If f.Extension.IsEmptyString Then
|
If f.Extension.IsEmptyString Then
|
||||||
@@ -1678,8 +1806,9 @@ BlockNullPicture:
|
|||||||
Case UTypes.Video, UTypes.m3u8 : f.Extension = "mp4"
|
Case UTypes.Video, UTypes.m3u8 : f.Extension = "mp4"
|
||||||
Case UTypes.GIF : f.Extension = "gif"
|
Case UTypes.GIF : f.Extension = "gif"
|
||||||
End Select
|
End Select
|
||||||
ElseIf f.Extension = "webp" And Settings.DownloadNativeImageFormat Then
|
ElseIf f.Extension = UserImage.ExtWebp And Settings.DownloadNativeImageFormat And Settings.FfmpegFile.Exists Then
|
||||||
f.Extension = "jpg"
|
'f.Extension = "jpg"
|
||||||
|
postProcessWebp = True
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If Not v.SpecialFolder.IsEmptyString Then
|
If Not v.SpecialFolder.IsEmptyString Then
|
||||||
@@ -1688,7 +1817,7 @@ BlockNullPicture:
|
|||||||
End If
|
End If
|
||||||
If __isVideo And vsf Then
|
If __isVideo And vsf Then
|
||||||
If v.SpecialFolder.IsEmptyString OrElse Not v.SpecialFolder.EndsWith("*") Then
|
If v.SpecialFolder.IsEmptyString OrElse Not v.SpecialFolder.EndsWith("*") Then
|
||||||
f.Path = $"{f.PathWithSeparator}Video"
|
f.Path = $"{f.PathWithSeparator}{VideoFolderName}"
|
||||||
If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
|
If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -1712,20 +1841,53 @@ BlockNullPicture:
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If __isVideo Then
|
updateDownCount(False)
|
||||||
v.Type = UTypes.Video
|
|
||||||
DownloadedVideos(False) += 1
|
|
||||||
ElseIf v.Type = UTypes.GIF Then
|
|
||||||
DownloadedPictures(False) += 1
|
|
||||||
Else
|
|
||||||
v.Type = UTypes.Picture
|
|
||||||
DownloadedPictures(False) += 1
|
|
||||||
End If
|
|
||||||
|
|
||||||
v.File = ChangeFileNameByProvider(f, v)
|
v.File = DownloadContentDefault_ConvertWebp(ChangeFileNameByProvider(f, v), postProcessWebp)
|
||||||
v.State = UStates.Downloaded
|
v.State = UStates.Downloaded
|
||||||
DownloadContentDefault_PostProcessing(v, f, Token)
|
DownloadContentDefault_PostProcessing(v, f, Token)
|
||||||
|
If UseMD5Comparison And (v.Type = UTypes.GIF Or v.Type = UTypes.Picture) Then
|
||||||
|
If v.File.Exists Then
|
||||||
|
v.MD5 = ValidateMD5_GetMD5(v, False)
|
||||||
|
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(False)
|
||||||
|
Else
|
||||||
|
_MD5List.Add(v.MD5)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
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
|
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
|
Catch woex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
__deleteFile.Invoke(f, v.URL_BASE)
|
__deleteFile.Invoke(f, v.URL_BASE)
|
||||||
v.State = UStates.Missing
|
v.State = UStates.Missing
|
||||||
@@ -1733,7 +1895,7 @@ BlockNullPicture:
|
|||||||
_ContentNew(i) = v
|
_ContentNew(i) = v
|
||||||
Throw woex
|
Throw woex
|
||||||
Catch wex As Exception
|
Catch wex As Exception
|
||||||
If DownloadContentDefault_ProcessDownloadException() Then
|
If Not v.Type = UTypes.Text AndAlso DownloadContentDefault_ProcessDownloadException() Then
|
||||||
v.Attempts += 1
|
v.Attempts += 1
|
||||||
v.State = UStates.Missing
|
v.State = UStates.Missing
|
||||||
If MissingErrorsAdd Then ErrorDownloading(f, v.URL)
|
If MissingErrorsAdd Then ErrorDownloading(f, v.URL)
|
||||||
@@ -1742,7 +1904,7 @@ BlockNullPicture:
|
|||||||
Else
|
Else
|
||||||
v.State = UStates.Skipped
|
v.State = UStates.Skipped
|
||||||
End If
|
End If
|
||||||
_ContentNew(i) = v
|
If Not __fileDeleted Then _ContentNew(i) = v
|
||||||
If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then
|
If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then
|
||||||
Progress.Perform(_ContentNew.Count - dTotal)
|
Progress.Perform(_ContentNew.Count - dTotal)
|
||||||
Exit Sub
|
Exit Sub
|
||||||
@@ -1781,6 +1943,22 @@ BlockNullPicture:
|
|||||||
End Function
|
End Function
|
||||||
Protected Overridable Sub DownloadContentDefault_PostProcessing(ByRef m As UserMedia, ByVal File As SFile, ByVal Token As CancellationToken)
|
Protected Overridable Sub DownloadContentDefault_PostProcessing(ByRef m As UserMedia, ByVal File As SFile, ByVal Token As CancellationToken)
|
||||||
End Sub
|
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
|
Protected Overridable Function DownloadContentDefault_ProcessDownloadException() As Boolean
|
||||||
Return True
|
Return True
|
||||||
End Function
|
End Function
|
||||||
@@ -1813,6 +1991,31 @@ BlockNullPicture:
|
|||||||
Protected Overridable Function CreateFileFromUrl(ByVal URL As String) As SFile
|
Protected Overridable Function CreateFileFromUrl(ByVal URL As String) As SFile
|
||||||
Return New SFile(URL)
|
Return New SFile(URL)
|
||||||
End Function
|
End Function
|
||||||
|
Protected Overridable Function SimpleDownloadAvatar(ByVal ImageAddress As String, Optional ByVal FileCreateFunc As Func(Of String, SFile) = Nothing,
|
||||||
|
Optional ByVal e As ErrorsDescriber = Nothing) As SFile
|
||||||
|
Try
|
||||||
|
If Not ImageAddress.IsEmptyString Then
|
||||||
|
Dim f As SFile
|
||||||
|
If FileCreateFunc Is Nothing Then
|
||||||
|
f = CreateFileFromUrl(ImageAddress)
|
||||||
|
Else
|
||||||
|
f = FileCreateFunc.Invoke(ImageAddress)
|
||||||
|
End If
|
||||||
|
If Not f.Name.IsEmptyString Then f.Name = f.Name.StringRemoveWinForbiddenSymbols.StringTrim
|
||||||
|
If Not f.Name.IsEmptyString Then
|
||||||
|
f.Path = DownloadContentDefault_GetRootDir()
|
||||||
|
f.Separator = "\"
|
||||||
|
If f.Extension.IsEmptyString Then f.Extension = "jpg"
|
||||||
|
If Not f.Exists Then GetWebFile(ImageAddress, f, EDP.ReturnValue)
|
||||||
|
If f.Exists Then IconBannerDownloaded = True : Return f
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return Nothing
|
||||||
|
Catch ex As Exception
|
||||||
|
If Not e.Exists Then e = New ErrorsDescriber(EDP.ReturnValue)
|
||||||
|
Return ErrorsDescriber.Execute(e, ex, $"SimpleDownloadAvatar({ImageAddress})", New SFile)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
Protected Overridable Function ChangeFileNameByProvider(ByVal f As SFile, ByVal m As UserMedia) As SFile
|
Protected Overridable Function ChangeFileNameByProvider(ByVal f As SFile, ByVal m As UserMedia) As SFile
|
||||||
Dim ff As SFile = Nothing
|
Dim ff As SFile = Nothing
|
||||||
Try
|
Try
|
||||||
@@ -1894,13 +2097,14 @@ BlockNullPicture:
|
|||||||
If m.Contains(IUserData.EraseMode.History) Then
|
If m.Contains(IUserData.EraseMode.History) Then
|
||||||
If MyFilePosts.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
|
If MyFilePosts.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
|
||||||
If MyFileData.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
|
If MyFileData.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
|
||||||
|
If MyMD5File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
|
||||||
LastUpdated = Nothing
|
LastUpdated = Nothing
|
||||||
EraseData_AdditionalDataFiles()
|
EraseData_AdditionalDataFiles()
|
||||||
UpdateUserInformation()
|
UpdateUserInformation()
|
||||||
End If
|
End If
|
||||||
If m.Contains(IUserData.EraseMode.Data) Then
|
If m.Contains(IUserData.EraseMode.Data) Then
|
||||||
Dim files As List(Of SFile) = SFile.GetFiles(DownloadContentDefault_GetRootDir.CSFileP,, SearchOption.AllDirectories, e)
|
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))
|
If files.ListExists Then files.ForEach(Sub(f) f.Delete(SFO.File, Settings.DeleteMode, e))
|
||||||
LatestData.Clear()
|
LatestData.Clear()
|
||||||
result = True
|
result = True
|
||||||
@@ -1910,6 +2114,8 @@ BlockNullPicture:
|
|||||||
_TempMediaList.Clear()
|
_TempMediaList.Clear()
|
||||||
_ContentNew.Clear()
|
_ContentNew.Clear()
|
||||||
_ContentList.Clear()
|
_ContentList.Clear()
|
||||||
|
_MD5List.Clear()
|
||||||
|
_MD5Loaded = False
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -1934,7 +2140,18 @@ BlockNullPicture:
|
|||||||
Return 0
|
Return 0
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Friend Overridable Function MoveFiles(ByVal __CollectionName As String, ByVal __SpecialCollectionPath As SFile) As Boolean Implements IUserData.MoveFiles
|
Friend Function SplitCollectionGetNewUserInfo() As SplitCollectionUserInfo
|
||||||
|
Dim u As New SplitCollectionUserInfo With {.UserOrig = User, .UserNew = User}
|
||||||
|
With u.UserNew
|
||||||
|
.CollectionName = String.Empty
|
||||||
|
.SpecialCollectionPath = Nothing
|
||||||
|
.UserModel = UsageModel.Default
|
||||||
|
.CollectionModel = UsageModel.Default
|
||||||
|
.UpdateUserFile()
|
||||||
|
End With
|
||||||
|
Return u
|
||||||
|
End Function
|
||||||
|
Friend Overridable Function MoveFiles(ByVal __CollectionName As String, ByVal __SpecialCollectionPath As SFile, Optional ByVal NewUser As SplitCollectionUserInfo? = Nothing) As Boolean Implements IUserData.MoveFiles
|
||||||
Dim UserBefore As UserInfo = User
|
Dim UserBefore As UserInfo = User
|
||||||
Dim Removed As Boolean = True
|
Dim Removed As Boolean = True
|
||||||
Dim _TurnBack As Boolean = False
|
Dim _TurnBack As Boolean = False
|
||||||
@@ -1950,6 +2167,7 @@ BlockNullPicture:
|
|||||||
User.SpecialCollectionPath = String.Empty
|
User.SpecialCollectionPath = String.Empty
|
||||||
User.UserModel = UsageModel.Default
|
User.UserModel = UsageModel.Default
|
||||||
User.CollectionModel = UsageModel.Default
|
User.CollectionModel = UsageModel.Default
|
||||||
|
If NewUser.HasValue Then User.SpecialPath = NewUser.Value.UserNew.SpecialPath
|
||||||
Else
|
Else
|
||||||
Settings.Users.Remove(Me)
|
Settings.Users.Remove(Me)
|
||||||
Removed = True
|
Removed = True
|
||||||
@@ -2099,6 +2317,7 @@ BlockNullPicture:
|
|||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Errors functions"
|
#Region "Errors functions"
|
||||||
|
''' <summary>ToStringForLog(): Message</summary>
|
||||||
Protected Sub LogError(ByVal ex As Exception, ByVal Message As String, Optional ByVal e As ErrorsDescriber = Nothing)
|
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}")
|
ErrorsDescriber.Execute(If(e.Exists, e, New ErrorsDescriber(EDP.SendToLog)), ex, $"{ToStringForLog()}: {Message}")
|
||||||
End Sub
|
End Sub
|
||||||
@@ -2129,6 +2348,17 @@ BlockNullPicture:
|
|||||||
Friend Function ToStringForLog() As String
|
Friend Function ToStringForLog() As String
|
||||||
Return $"{IIf(IncludedInCollection, $"[{CollectionName}] - ", String.Empty)}[{Site}] - {Name}"
|
Return $"{IIf(IncludedInCollection, $"[{CollectionName}] - ", String.Empty)}[{Site}] - {Name}"
|
||||||
End Function
|
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
|
Public Overrides Function ToString() As String
|
||||||
If IsCollection Then
|
If IsCollection Then
|
||||||
Return CollectionName
|
Return CollectionName
|
||||||
@@ -2150,6 +2380,12 @@ BlockNullPicture:
|
|||||||
Private Sub BTT_CONTEXT_DOWN_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN.KeyClick
|
Private Sub BTT_CONTEXT_DOWN_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN.KeyClick
|
||||||
Downloader.Add(Me, e.IncludeInTheFeed)
|
Downloader.Add(Me, e.IncludeInTheFeed)
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub BTT_CONTEXT_DOWN_LIMIT_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN_LIMIT.KeyClick
|
||||||
|
ControlInvokeFast(MainFrameObj.MF, Sub() MainFrameObj.MF.DownloadSelectedUser(MainFrame.DownUserLimits.Number, e.IncludeInTheFeed, Me), EDP.SendToLog)
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_CONTEXT_DOWN_DATE_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN_DATE.KeyClick
|
||||||
|
ControlInvokeFast(MainFrameObj.MF, Sub() MainFrameObj.MF.DownloadSelectedUser(MainFrame.DownUserLimits.Date, e.IncludeInTheFeed, Me), EDP.SendToLog)
|
||||||
|
End Sub
|
||||||
Private Sub BTT_CONTEXT_EDIT_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_EDIT.Click
|
Private Sub BTT_CONTEXT_EDIT_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_EDIT.Click
|
||||||
Using f As New Editors.UserCreatorForm(Me)
|
Using f As New Editors.UserCreatorForm(Me)
|
||||||
f.ShowDialog()
|
f.ShowDialog()
|
||||||
@@ -2225,10 +2461,14 @@ BlockNullPicture:
|
|||||||
LatestData.Clear()
|
LatestData.Clear()
|
||||||
_TempMediaList.Clear()
|
_TempMediaList.Clear()
|
||||||
_TempPostsList.Clear()
|
_TempPostsList.Clear()
|
||||||
|
_MD5List.Clear()
|
||||||
TokenPersonal = Nothing
|
TokenPersonal = Nothing
|
||||||
|
GDLFileNameProvider = Nothing
|
||||||
If Not ProgressPre Is Nothing Then ProgressPre.Reset() : ProgressPre.Dispose()
|
If Not ProgressPre Is Nothing Then ProgressPre.Reset() : ProgressPre.Dispose()
|
||||||
If Not Responser Is Nothing Then Responser.Dispose()
|
If Not Responser Is Nothing Then Responser.Dispose()
|
||||||
If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose()
|
If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose()
|
||||||
|
If Not BTT_CONTEXT_DOWN_LIMIT Is Nothing Then BTT_CONTEXT_DOWN_LIMIT.Dispose()
|
||||||
|
If Not BTT_CONTEXT_DOWN_DATE Is Nothing Then BTT_CONTEXT_DOWN_DATE.Dispose()
|
||||||
If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose()
|
If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose()
|
||||||
If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose()
|
If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose()
|
||||||
If Not BTT_CONTEXT_ERASE Is Nothing Then BTT_CONTEXT_ERASE.Dispose()
|
If Not BTT_CONTEXT_ERASE Is Nothing Then BTT_CONTEXT_ERASE.Dispose()
|
||||||
|
|||||||
@@ -8,11 +8,8 @@
|
|||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Namespace API.Base.YTDLP
|
Namespace API.Base.YTDLP
|
||||||
Friend Class YTDLPBatch : Inherits GDL.GDLBatch
|
Friend Class YTDLPBatch : Inherits GDL.GDLBatch
|
||||||
Friend Sub New(ByVal _Token As Threading.CancellationToken)
|
Friend Sub New(ByVal _Token As Threading.CancellationToken, Optional ByVal __MainProcessName As String = Nothing, Optional ByVal WorkingDir As SFile = Nothing)
|
||||||
MyBase.New(_Token)
|
MyBase.New(_Token, __MainProcessName.IfNullOrEmpty(Settings.YtdlpFile.File.Name), WorkingDir.IfNullOrEmpty(Settings.YtdlpFile.File))
|
||||||
Commands.Clear()
|
|
||||||
MainProcessName = Settings.YtdlpFile.File.Name '"yt-dlp"
|
|
||||||
ChangeDirectory(Settings.YtdlpFile.File)
|
|
||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -134,6 +134,7 @@ Namespace API.Base
|
|||||||
m.GetMemberCustomAttributes(Of Provider).ListExists
|
m.GetMemberCustomAttributes(Of Provider).ListExists
|
||||||
Dim m1 As MemberInfo, m2 As MemberInfo
|
Dim m1 As MemberInfo, m2 As MemberInfo
|
||||||
Dim tmpObj As Object
|
Dim tmpObj As Object
|
||||||
|
Dim maxOffset%
|
||||||
|
|
||||||
members = GetObjectMembers(MyObject, Function(m) (m.MemberType = MemberTypes.Field Or m.MemberType = MemberTypes.Property) AndAlso
|
members = GetObjectMembers(MyObject, Function(m) (m.MemberType = MemberTypes.Field Or m.MemberType = MemberTypes.Property) AndAlso
|
||||||
Not m.GetCustomAttribute(Of PSettingAttribute) Is Nothing,, True,
|
Not m.GetCustomAttribute(Of PSettingAttribute) Is Nothing,, True,
|
||||||
@@ -175,6 +176,9 @@ Namespace API.Base
|
|||||||
|
|
||||||
If MyMembers.Count > 0 Then
|
If MyMembers.Count > 0 Then
|
||||||
|
|
||||||
|
maxOffset = MyMembers.Max(Function(mm) mm.LeftOffset)
|
||||||
|
If maxOffset > 0 Then MyMembers.ForEach(Sub(mm) mm.LeftOffset = maxOffset)
|
||||||
|
|
||||||
Dim prov As IEnumerable(Of Provider)
|
Dim prov As IEnumerable(Of Provider)
|
||||||
Dim _prov As Provider
|
Dim _prov As Provider
|
||||||
Dim si% = -1
|
Dim si% = -1
|
||||||
|
|||||||
28
SCrawler/API/BaseObjects/SplitCollectionUserInfo.vb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
' 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.Base
|
||||||
|
Friend Structure SplitCollectionUserInfo
|
||||||
|
Friend UserOrig As UserInfo
|
||||||
|
Friend UserNew As UserInfo
|
||||||
|
Friend Changed As Boolean
|
||||||
|
Friend ReadOnly Property SameDrive As Boolean
|
||||||
|
Get
|
||||||
|
Return GetUserDrive(UserOrig) = GetUserDrive(UserNew)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Private Shared Function GetUserDrive(ByVal User As UserInfo) As String
|
||||||
|
Dim u As UserInfo = User
|
||||||
|
If u.File.IsEmptyString Then u.UpdateUserFile()
|
||||||
|
Return u.File.Segments.FirstOrDefault.StringToLower
|
||||||
|
End Function
|
||||||
|
Public Overrides Function ToString() As String
|
||||||
|
Return $"[{UserOrig.File.CutPath.PathWithSeparator}] -> [{UserNew.File.CutPath.PathWithSeparator}]"
|
||||||
|
End Function
|
||||||
|
End Structure
|
||||||
|
End Namespace
|
||||||
111
SCrawler/API/BaseObjects/SplitCollectionUserInfoChangePathsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
' 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.Base
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class SplitCollectionUserInfoChangePathsForm : 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 LBL_INFO As System.Windows.Forms.Label
|
||||||
|
Me.LIST_USERS = New System.Windows.Forms.ListBox()
|
||||||
|
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||||
|
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||||
|
LBL_INFO = New System.Windows.Forms.Label()
|
||||||
|
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||||
|
CONTAINER_MAIN.SuspendLayout()
|
||||||
|
TP_MAIN.SuspendLayout()
|
||||||
|
Me.SuspendLayout()
|
||||||
|
'
|
||||||
|
'CONTAINER_MAIN
|
||||||
|
'
|
||||||
|
'
|
||||||
|
'CONTAINER_MAIN.ContentPanel
|
||||||
|
'
|
||||||
|
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||||
|
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 261)
|
||||||
|
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, 261)
|
||||||
|
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(LBL_INFO, 0, 0)
|
||||||
|
TP_MAIN.Controls.Add(Me.LIST_USERS, 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, 50.0!))
|
||||||
|
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
|
TP_MAIN.Size = New System.Drawing.Size(384, 261)
|
||||||
|
TP_MAIN.TabIndex = 0
|
||||||
|
'
|
||||||
|
'LBL_INFO
|
||||||
|
'
|
||||||
|
LBL_INFO.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
LBL_INFO.Location = New System.Drawing.Point(3, 0)
|
||||||
|
LBL_INFO.Name = "LBL_INFO"
|
||||||
|
LBL_INFO.Size = New System.Drawing.Size(378, 50)
|
||||||
|
LBL_INFO.TabIndex = 0
|
||||||
|
LBL_INFO.Text = "Check the user destination paths and change them if necessary." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Double-click to c" &
|
||||||
|
"hange."
|
||||||
|
LBL_INFO.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
|
||||||
|
'
|
||||||
|
'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, 53)
|
||||||
|
Me.LIST_USERS.Name = "LIST_USERS"
|
||||||
|
Me.LIST_USERS.Size = New System.Drawing.Size(378, 205)
|
||||||
|
Me.LIST_USERS.TabIndex = 1
|
||||||
|
'
|
||||||
|
'SplitCollectionUserInfoChangePathsForm
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(384, 261)
|
||||||
|
Me.Controls.Add(CONTAINER_MAIN)
|
||||||
|
Me.Icon = Global.SCrawler.My.Resources.Resources.UsersIcon_32
|
||||||
|
Me.KeyPreview = True
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(400, 300)
|
||||||
|
Me.Name = "SplitCollectionUserInfoChangePathsForm"
|
||||||
|
Me.ShowInTaskbar = False
|
||||||
|
Me.Text = "Collection users"
|
||||||
|
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||||
|
CONTAINER_MAIN.ResumeLayout(False)
|
||||||
|
CONTAINER_MAIN.PerformLayout()
|
||||||
|
TP_MAIN.ResumeLayout(False)
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents LIST_USERS As ListBox
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -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="LBL_INFO.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
' 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.Functions.Messaging
|
||||||
|
Namespace API.Base
|
||||||
|
Friend Class SplitCollectionUserInfoChangePathsForm
|
||||||
|
Private WithEvents MyDefs As DefaultFormOptions
|
||||||
|
Friend ReadOnly Property Users As List(Of SplitCollectionUserInfo)
|
||||||
|
''' <summary>
|
||||||
|
''' Cancel = use initial<br/>
|
||||||
|
''' Abort = abort operation<br/>
|
||||||
|
''' OK = use changes
|
||||||
|
''' </summary>
|
||||||
|
Friend Sub New(ByVal _Users As IEnumerable(Of SplitCollectionUserInfo))
|
||||||
|
InitializeComponent()
|
||||||
|
MyDefs = New DefaultFormOptions(Me, Settings.Design)
|
||||||
|
Users = New List(Of SplitCollectionUserInfo)(_Users)
|
||||||
|
End Sub
|
||||||
|
Private Sub SplitCollectionUserInfoChangePathsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
With MyDefs
|
||||||
|
.MyViewInitialize()
|
||||||
|
.AddOkCancelToolbar()
|
||||||
|
LIST_USERS.Items.AddRange(Users.Cast(Of Object).ToArray)
|
||||||
|
.EndLoaderOperations()
|
||||||
|
.MyOkCancel.EnableOK = True
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||||
|
MyDefs.CloseForm()
|
||||||
|
End Sub
|
||||||
|
Private Sub MyDefs_ButtonCancelClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonCancelClick
|
||||||
|
Dim m As New MMessage("You have canceled the change. Do you want to process user(s) as is or cancel the operation?", "Change user paths",
|
||||||
|
{New MsgBoxButton("Initial", "Process users as is (IGNORE changes to this form)") With {.CallBackObject = DialogResult.Cancel},
|
||||||
|
New MsgBoxButton("Process", "Process users as is (INCLUDE changes here)") With {.CallBackObject = DialogResult.OK},
|
||||||
|
New MsgBoxButton("Abort", "Abort operation") With {.CallBackObject = DialogResult.Abort},
|
||||||
|
New MsgBoxButton("Cancel", "Continue editing here") With {.CallBackObject = DialogResult.Retry}},
|
||||||
|
vbExclamation) With {.ButtonsPerRow = 4}
|
||||||
|
Dim result As DialogResult = CInt(MsgBoxE(m).Button.CallBackObject)
|
||||||
|
If result = DialogResult.Retry Then
|
||||||
|
e.Handled = True
|
||||||
|
Exit Sub
|
||||||
|
Else
|
||||||
|
MyDefs.CloseForm(result)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub SplitCollectionUserInfoChangePathsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||||
|
Users.Clear()
|
||||||
|
End Sub
|
||||||
|
Private Sub LIST_USERS_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LIST_USERS.MouseDoubleClick
|
||||||
|
Try
|
||||||
|
With LIST_USERS
|
||||||
|
If .SelectedIndex >= 0 Then
|
||||||
|
Dim obj As SplitCollectionUserInfo = .Items(.SelectedIndex)
|
||||||
|
Using f As New SplitCollectionUserInfoPathForm(obj)
|
||||||
|
f.ShowDialog()
|
||||||
|
If f.DialogResult = DialogResult.OK Then
|
||||||
|
obj = f.User
|
||||||
|
If obj.Changed Then
|
||||||
|
Users(.SelectedIndex) = obj
|
||||||
|
.Items(.SelectedIndex) = obj
|
||||||
|
.Refresh()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Catch ex As Exception
|
||||||
|
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Change user paths")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
134
SCrawler/API/BaseObjects/SplitCollectionUserInfoPathForm.Designer.vb
generated
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
' 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.Base
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class SplitCollectionUserInfoPathForm : 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(SplitCollectionUserInfoPathForm))
|
||||||
|
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||||
|
Me.TXT_PATH_CURR = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
|
Me.TXT_PATH_NEW = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
|
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||||
|
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||||
|
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||||
|
CONTAINER_MAIN.SuspendLayout()
|
||||||
|
TP_MAIN.SuspendLayout()
|
||||||
|
CType(Me.TXT_PATH_CURR, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
|
CType(Me.TXT_PATH_NEW, 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(484, 84)
|
||||||
|
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||||
|
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
|
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||||
|
CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||||
|
CONTAINER_MAIN.Size = New System.Drawing.Size(484, 84)
|
||||||
|
CONTAINER_MAIN.TabIndex = 0
|
||||||
|
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||||
|
'
|
||||||
|
'TP_MAIN
|
||||||
|
'
|
||||||
|
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||||
|
TP_MAIN.ColumnCount = 1
|
||||||
|
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
|
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||||
|
TP_MAIN.Controls.Add(Me.TXT_PATH_CURR, 0, 0)
|
||||||
|
TP_MAIN.Controls.Add(Me.TXT_PATH_NEW, 0, 1)
|
||||||
|
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
|
TP_MAIN.Name = "TP_MAIN"
|
||||||
|
TP_MAIN.RowCount = 3
|
||||||
|
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
|
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
|
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
|
TP_MAIN.Size = New System.Drawing.Size(484, 84)
|
||||||
|
TP_MAIN.TabIndex = 0
|
||||||
|
'
|
||||||
|
'TXT_PATH_CURR
|
||||||
|
'
|
||||||
|
Me.TXT_PATH_CURR.CaptionText = "Current"
|
||||||
|
Me.TXT_PATH_CURR.CaptionWidth = 50.0R
|
||||||
|
Me.TXT_PATH_CURR.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.TXT_PATH_CURR.Location = New System.Drawing.Point(4, 4)
|
||||||
|
Me.TXT_PATH_CURR.Name = "TXT_PATH_CURR"
|
||||||
|
Me.TXT_PATH_CURR.Size = New System.Drawing.Size(476, 22)
|
||||||
|
Me.TXT_PATH_CURR.TabIndex = 0
|
||||||
|
Me.TXT_PATH_CURR.TextBoxReadOnly = True
|
||||||
|
'
|
||||||
|
'TXT_PATH_NEW
|
||||||
|
'
|
||||||
|
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||||
|
ActionButton1.Name = "Refresh"
|
||||||
|
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
|
||||||
|
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||||
|
ActionButton2.Name = "Open"
|
||||||
|
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||||
|
Me.TXT_PATH_NEW.Buttons.Add(ActionButton1)
|
||||||
|
Me.TXT_PATH_NEW.Buttons.Add(ActionButton2)
|
||||||
|
Me.TXT_PATH_NEW.CaptionText = "New"
|
||||||
|
Me.TXT_PATH_NEW.CaptionWidth = 50.0R
|
||||||
|
Me.TXT_PATH_NEW.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.TXT_PATH_NEW.Location = New System.Drawing.Point(4, 33)
|
||||||
|
Me.TXT_PATH_NEW.Name = "TXT_PATH_NEW"
|
||||||
|
Me.TXT_PATH_NEW.Size = New System.Drawing.Size(476, 22)
|
||||||
|
Me.TXT_PATH_NEW.TabIndex = 1
|
||||||
|
'
|
||||||
|
'SplitCollectionUserInfoPathForm
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(484, 84)
|
||||||
|
Me.Controls.Add(CONTAINER_MAIN)
|
||||||
|
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||||
|
Me.Icon = Global.SCrawler.My.Resources.Resources.UsersIcon_32
|
||||||
|
Me.KeyPreview = True
|
||||||
|
Me.MaximizeBox = False
|
||||||
|
Me.MaximumSize = New System.Drawing.Size(500, 123)
|
||||||
|
Me.MinimizeBox = False
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(500, 123)
|
||||||
|
Me.Name = "SplitCollectionUserInfoPathForm"
|
||||||
|
Me.ShowInTaskbar = False
|
||||||
|
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||||
|
Me.Text = "User paths"
|
||||||
|
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||||
|
CONTAINER_MAIN.ResumeLayout(False)
|
||||||
|
CONTAINER_MAIN.PerformLayout()
|
||||||
|
TP_MAIN.ResumeLayout(False)
|
||||||
|
CType(Me.TXT_PATH_CURR, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
|
CType(Me.TXT_PATH_NEW, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents TXT_PATH_CURR As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
|
Private WithEvents TXT_PATH_NEW As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
154
SCrawler/API/BaseObjects/SplitCollectionUserInfoPathForm.resx
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<?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/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||||
|
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
|
||||||
|
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
|
||||||
|
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
|
||||||
|
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
|
||||||
|
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
|
||||||
|
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
|
||||||
|
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
|
||||||
|
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
|
||||||
|
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
|
||||||
|
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
|
||||||
|
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
|
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||||
|
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||||
|
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||||
|
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||||
|
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||||
|
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
68
SCrawler/API/BaseObjects/SplitCollectionUserInfoPathForm.vb
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
' 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.Controls.Base
|
||||||
|
Imports SCrawler.DownloadObjects.STDownloader
|
||||||
|
Namespace API.Base
|
||||||
|
Friend Class SplitCollectionUserInfoPathForm
|
||||||
|
Private WithEvents MyDefs As DefaultFormOptions
|
||||||
|
Friend User As SplitCollectionUserInfo
|
||||||
|
Private ReadOnly UserNewPathDef As String
|
||||||
|
Friend Sub New(ByVal _User As SplitCollectionUserInfo)
|
||||||
|
InitializeComponent()
|
||||||
|
MyDefs = New DefaultFormOptions(Me, Settings.Design)
|
||||||
|
User = _User
|
||||||
|
UserNewPathDef = User.UserNew.File.CutPath.PathWithSeparator
|
||||||
|
End Sub
|
||||||
|
Private Sub SplitCollectionUserInfoPathForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
With MyDefs
|
||||||
|
.MyViewInitialize()
|
||||||
|
.AddOkCancelToolbar()
|
||||||
|
|
||||||
|
TXT_PATH_CURR.Text = User.UserOrig.File.CutPath.PathWithSeparator
|
||||||
|
TXT_PATH_NEW.Text = UserNewPathDef
|
||||||
|
|
||||||
|
.MyFieldsCheckerE = New FieldsChecker
|
||||||
|
.MyFieldsCheckerE.AddControl(Of String)(TXT_PATH_NEW, "New path")
|
||||||
|
.MyFieldsCheckerE.EndLoaderOperations()
|
||||||
|
|
||||||
|
.EndLoaderOperations()
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||||
|
If MyDefs.MyFieldsChecker.AllParamsOK Then MyDefs.CloseForm()
|
||||||
|
End Sub
|
||||||
|
Private Sub TXT_PATH_NEW_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_PATH_NEW.ActionOnButtonClick
|
||||||
|
Select Case e.DefaultButton
|
||||||
|
Case ActionButton.DefaultButtons.Refresh : TXT_PATH_NEW.Text = UserNewPathDef
|
||||||
|
Case ActionButton.DefaultButtons.Open
|
||||||
|
Using ff As New Editors.GlobalLocationsChooserForm With {.MyInitialLocation = TXT_PATH_NEW.Text}
|
||||||
|
ff.ShowDialog()
|
||||||
|
If ff.DialogResult = DialogResult.OK Then
|
||||||
|
Dim dest As DownloadLocation = ff.MyDestination
|
||||||
|
If Not dest.Path.IsEmptyString Then
|
||||||
|
Dim ph As PathMoverHandler = Editors.GlobalLocationsChooserForm.ModelHandler(dest.Model)
|
||||||
|
If Not ph Is Nothing Then TXT_PATH_NEW.Text = ph.Invoke(User.UserNew, dest.Path.CSFileP).ToString
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
End Select
|
||||||
|
End Sub
|
||||||
|
Private Sub TXT_PATH_NEW_ActionOnTextChanged(sender As Object, e As EventArgs) Handles TXT_PATH_NEW.ActionOnTextChanged
|
||||||
|
If Not MyDefs.Initializing Then
|
||||||
|
Dim f As SFile = TXT_PATH_NEW.Text.CSFileP
|
||||||
|
If Not f.IsEmptyString Then
|
||||||
|
User.UserNew.SpecialPath = f
|
||||||
|
User.UserNew.UpdateUserFile()
|
||||||
|
User.Changed = Not User.UserNew.File.CutPath.PathWithSeparator = UserNewPathDef
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
18
SCrawler/API/Bluesky/Declarations.vb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
' 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.Functions.RegularExpressions
|
||||||
|
Namespace API.Bluesky
|
||||||
|
Friend Module Declarations
|
||||||
|
Friend Const BlueskySiteKey As String = "AndyProgram_Bluesky"
|
||||||
|
Friend ReadOnly DateProvider As New ADateTime("yyyy-MM-ddTHH:mm:ss.FFF%K")
|
||||||
|
Friend ReadOnly RegEx_PlayLists As RParams = RParams.DM("RESOLUTION=\d+x(\d+)\s*(\S+)", 0, RegexReturn.List, EDP.ReturnValue)
|
||||||
|
Friend ReadOnly RegEx_FilePattern As RParams = RParams.DM("(.+?)(\.|@)(gif|m3u8|[^/\?\&]+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
|
||||||
|
Friend ReadOnly RegEx_SinglePostPattern As RParams = RParams.DM("profile/([^/]+)/post/([^/\?\&]+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
51
SCrawler/API/Bluesky/M3U8.vb
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
' 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 System.Threading
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Namespace API.Bluesky
|
||||||
|
Friend NotInheritable Class M3U8
|
||||||
|
Private Sub New()
|
||||||
|
End Sub
|
||||||
|
Private Shared Function GetUrlsList(ByVal URL As String) As List(Of String)
|
||||||
|
Using resp As New Responser With {.AllowAutoRedirect = False}
|
||||||
|
Dim r$ = resp.GetResponse(URL)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Dim file$ = String.Empty, appender$
|
||||||
|
Dim files As List(Of Sizes) = RegexFields(Of Sizes)(r, {RegEx_PlayLists}, {1, 2})
|
||||||
|
If files.ListExists Then files.RemoveAll(Function(ff) ff.Value = 0 Or ff.Data.IsEmptyString)
|
||||||
|
If files.ListExists Then
|
||||||
|
files.Sort()
|
||||||
|
file = files(0).Data
|
||||||
|
appender = URL.Replace(URL.Split("/").Last, String.Empty)
|
||||||
|
file = M3U8Base.CreateUrl(appender, file)
|
||||||
|
If Not file.IsEmptyString Then
|
||||||
|
r = resp.GetResponse(file)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Dim l As List(Of String) = RegexReplace(r, M3U8Declarations.TsFilesRegEx)
|
||||||
|
If l.ListExists Then
|
||||||
|
appender = file.Replace(file.Split("/").Last, String.Empty)
|
||||||
|
For i% = 0 To l.Count - 1 : l(i) = M3U8Base.CreateUrl(appender, l(i)) : Next
|
||||||
|
Return l
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Friend Shared Function Download(ByVal URL As String, ByVal Destination As SFile, ByVal Token As CancellationToken,
|
||||||
|
ByVal Progress As MyProgress, ByVal UsePreProgress As Boolean) As SFile
|
||||||
|
Return M3U8Base.Download(GetUrlsList(URL), Destination,, Token, Progress, UsePreProgress)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
100
SCrawler/API/Bluesky/SiteSettings.vb
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
' 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.Base
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports SCrawler.Plugin.Attributes
|
||||||
|
Imports PersonalUtilities.Functions.XML
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
|
Namespace API.Bluesky
|
||||||
|
<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
|
||||||
|
<PropertyOption(ControlText:="User name", IsAuth:=True, AllowNull:=False), PXML>
|
||||||
|
Friend ReadOnly Property UserHandle As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="Password", IsAuth:=True, AllowNull:=False), PXML>
|
||||||
|
Friend ReadOnly Property UserPassword As PropertyValue
|
||||||
|
<PXML> Friend ReadOnly Property Token As PropertyValue
|
||||||
|
<PXML> Friend ReadOnly Property TokenUpdateTime As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="Token update", ControlToolTip:="Token refresh interval (in minutes)." & vbCr & "Default: 120.", IsAuth:=True), PXML, PClonable, HiddenControl>
|
||||||
|
Friend ReadOnly Property TokenRefreshInterval As PropertyValue
|
||||||
|
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||||
|
MyBase.New("Bluesky", "bsky.app", AccName, Temp, My.Resources.SiteResources.BlueskyIcon_32, My.Resources.SiteResources.BlueskyPic_32)
|
||||||
|
|
||||||
|
Responser.ContentType = "application/json"
|
||||||
|
|
||||||
|
CookiesEnabled = New PropertyValue(False)
|
||||||
|
UserHandle = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
UserPassword = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
Token = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
TokenUpdateTime = New PropertyValue(Now.AddYears(-1))
|
||||||
|
TokenRefreshInterval = New PropertyValue(120)
|
||||||
|
|
||||||
|
_AllowUserAgentUpdate = False
|
||||||
|
UrlPatternUser = "https://bsky.app/profile/{0}"
|
||||||
|
ImageVideoContains = "bsky.app"
|
||||||
|
UserRegex = RParams.DMS("bsky.app/profile/([^/\?]+)", 1, EDP.ReturnValue)
|
||||||
|
UserOptionsType = GetType(EditorExchangeOptionsBase)
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Function UserOptionsValid(ByVal Options As Object) As Boolean
|
||||||
|
Return DirectCast(Options, EditorExchangeOptionsBase).SiteKey = BlueskySiteKey
|
||||||
|
End Function
|
||||||
|
Protected Overrides Sub UserOptionsSetParameters(ByRef Options As Object)
|
||||||
|
DirectCast(Options, EditorExchangeOptionsBase).SiteKey = BlueskySiteKey
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
|
||||||
|
Return New UserData
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function BaseAuthExists() As Boolean
|
||||||
|
Return Not CStr(UserHandle.Value).IsEmptyString And Not CStr(UserPassword.Value).IsEmptyString
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||||
|
Return MyBase.Available(What, Silent) AndAlso UpdateToken()
|
||||||
|
End Function
|
||||||
|
Private _TokenUpdating As Boolean = False
|
||||||
|
Friend Function UpdateToken(Optional ByVal Force As Boolean = False) As Boolean
|
||||||
|
Try
|
||||||
|
While _TokenUpdating : Threading.Thread.Sleep(100) : End While
|
||||||
|
_TokenUpdating = True
|
||||||
|
If BaseAuthExists() Then
|
||||||
|
If CDate(TokenUpdateTime.Value).AddMinutes(TokenRefreshInterval.Value) < Now Or Force Then
|
||||||
|
Using resp As Responser = Responser.Copy
|
||||||
|
With resp
|
||||||
|
.Mode = Responser.Modes.Curl
|
||||||
|
.Method = "POST"
|
||||||
|
.CurlSslNoRevoke = True
|
||||||
|
.CurlInsecure = True
|
||||||
|
.CurlArgumentsLeft = "-d ""{\" & $"""identifier\"": \""{UserHandle.Value}\"", \""password\"": \""{UserPassword.Value}\""" & "}"""
|
||||||
|
|
||||||
|
Dim r$ = .GetResponse("https://bsky.social/xrpc/com.atproto.server.createSession")
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
||||||
|
If j.ListExists Then
|
||||||
|
Dim t$ = j.Value("accessJwt")
|
||||||
|
If Not t.IsEmptyString Then Token.Value = $"Bearer {t}" : TokenUpdateTime.Value = Now : Return True
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Using
|
||||||
|
Else
|
||||||
|
Return True
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return False
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "Bluesky.SiteSettings.UpdateToken", False)
|
||||||
|
Finally
|
||||||
|
_TokenUpdating = False
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
382
SCrawler/API/Bluesky/UserData.vb
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
' 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 System.Threading
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports SCrawler.API.YouTube.Objects
|
||||||
|
Imports PersonalUtilities.Functions.XML
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
|
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||||
|
Namespace API.Bluesky
|
||||||
|
Friend Class UserData : Inherits UserDataBase
|
||||||
|
#Region "Declarations"
|
||||||
|
Private ReadOnly Property MySettings As SiteSettings
|
||||||
|
Get
|
||||||
|
Return HOST.Source
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Private ReadOnly Property ID_Encoded As String
|
||||||
|
Get
|
||||||
|
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)
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||||
|
Return New EditorExchangeOptionsBase(Me) With {.SiteKey = BlueskySiteKey}
|
||||||
|
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 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"
|
||||||
|
Private Function UpdateToken(Optional ByVal Force As Boolean = False, Optional ByVal OnlyAddHeader As Boolean = False) As Boolean
|
||||||
|
Dim process As Boolean = True
|
||||||
|
If CDate(MySettings.TokenUpdateTime.Value).AddHours(2) <= Now Or Force Then
|
||||||
|
process = MySettings.UpdateToken(Force)
|
||||||
|
If process Then _TokenUpdateCount += 1
|
||||||
|
End If
|
||||||
|
If process Or OnlyAddHeader Then Responser.Headers.Add("authorization", MySettings.Token.Value)
|
||||||
|
Return Not Responser.Headers.Value("authorization").IsEmptyString
|
||||||
|
End Function
|
||||||
|
Private _TokenUpdateCount As Integer = 0
|
||||||
|
Private Sub TokenUpdateCountReset()
|
||||||
|
_TokenUpdateCount = 0
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Download"
|
||||||
|
Private _PostCount As Integer = 0
|
||||||
|
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||||
|
_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 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%
|
||||||
|
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
|
||||||
|
nextCursor = j.Value("cursor")
|
||||||
|
With j(n)
|
||||||
|
If .ListExists Then
|
||||||
|
For Each post As EContainer In .Self
|
||||||
|
With post(p)
|
||||||
|
c = DefaultParser(.Self,, nextCursor)
|
||||||
|
Select Case c
|
||||||
|
Case CInt(DateResult.Skip) * -1 : Continue For
|
||||||
|
Case CInt(DateResult.Exit) * -1 : Exit Sub
|
||||||
|
Case Is > 0 : _PostCount += c
|
||||||
|
End Select
|
||||||
|
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
|
||||||
|
End Using
|
||||||
|
|
||||||
|
If Not nextCursor.IsEmptyString Then DownloadData(nextCursor, Token)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
ProcessException(ex, Token, $"DownloadData({URL})")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "DefaultParser"
|
||||||
|
Private Const Down_ImageAddress As String = "https://cdn.bsky.app/img/feed_fullsize/plain/{0}/{1}"
|
||||||
|
Private Function GetPostID(ByVal PostUri As String) As String
|
||||||
|
Return If(PostUri.IsEmptyString, String.Empty, PostUri.Split("/").LastOrDefault)
|
||||||
|
End Function
|
||||||
|
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
|
||||||
|
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
|
||||||
|
Dim d As EContainer
|
||||||
|
With e
|
||||||
|
If .ListExists Then
|
||||||
|
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")
|
||||||
|
If Not IsSavedPosts Then NextCursor = postDate
|
||||||
|
If CheckDateLimits Then
|
||||||
|
Select Case CheckDatesLimit(postDate, DateProvider)
|
||||||
|
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 _TmpPosts2.Add(postID)
|
||||||
|
End If
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Dim createMedia As Func(Of String, UTypes, UserMedia) =
|
||||||
|
Function(ByVal url As String, ByVal type As UTypes) As UserMedia
|
||||||
|
m = New UserMedia(url, type) With {
|
||||||
|
.URL_BASE = __urlBase,
|
||||||
|
.File = CreateFileFromUrl(url, type),
|
||||||
|
.Post = New UserPost(postID, If(AConvert(Of Date)(postDate, DateProvider, Nothing, EDP.ReturnValue), Nothing)),
|
||||||
|
.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
|
||||||
|
|
||||||
|
If If(.Item("images")?.Count, 0) > 0 Then
|
||||||
|
With .Item("images")
|
||||||
|
For Each d In .Self
|
||||||
|
updateUrl = False
|
||||||
|
__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
|
||||||
|
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
|
||||||
|
__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
|
||||||
|
|
||||||
|
If c > 0 Then Exit For
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Return c
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
#Region "GetProfileInfo"
|
||||||
|
Private Sub GetProfileInfo(ByVal Token As CancellationToken)
|
||||||
|
Try
|
||||||
|
If UpdateToken() Then
|
||||||
|
Dim r$ = Responser.GetResponse($"https://bsky.social/xrpc/app.bsky.actor.getProfile?actor={ID.IfNullOrEmpty(NameTrue)}")
|
||||||
|
TokenUpdateCountReset()
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Using j As EContainer = JsonDocument.Parse(r)
|
||||||
|
If j.ListExists Then
|
||||||
|
ID = j.Value("did")
|
||||||
|
UserSiteNameUpdate(j.Value("displayName"))
|
||||||
|
UserDescriptionUpdate(j.Value("description"))
|
||||||
|
NameTrue = j.Value("handle")
|
||||||
|
SimpleDownloadAvatar(j.Value("avatar"))
|
||||||
|
SimpleDownloadAvatar(j.Value("banner"))
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Throw New ArgumentException("Token is null", "Token")
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
ProcessException(ex, Token, "GetProfileInfo")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "ReparseMissing"
|
||||||
|
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
||||||
|
Const uriPattern$ = "at://{0}/app.bsky.feed.post/{1}"
|
||||||
|
Dim rList As New List(Of Integer)
|
||||||
|
Try
|
||||||
|
If ContentMissingExists AndAlso UpdateToken() Then
|
||||||
|
Dim r$, url$, uri$
|
||||||
|
Dim tu As Byte
|
||||||
|
Dim m As UserMedia
|
||||||
|
Dim j As EContainer
|
||||||
|
For i% = 0 To _ContentList.Count - 1
|
||||||
|
m = _ContentList(i)
|
||||||
|
If m.State = UStates.Missing Then
|
||||||
|
uri = SymbolsConverter.ASCII.EncodeSymbolsOnly(String.Format(uriPattern, NameTrue, m.Post.ID))
|
||||||
|
url = $"https://bsky.social/xrpc/app.bsky.feed.getPostThread?uri={uri}&depth=10"
|
||||||
|
For tu = 0 To 1
|
||||||
|
Try
|
||||||
|
Responser.ResetStatus()
|
||||||
|
r = Responser.GetResponse(url)
|
||||||
|
TokenUpdateCountReset()
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
j = JsonDocument.Parse(r)
|
||||||
|
If j.ListExists Then
|
||||||
|
If DefaultParser(j({"thread", "post"}), False,, False, UStates.Missing) > 0 Then rList.Add(i)
|
||||||
|
j.Dispose()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Exit For
|
||||||
|
Catch eex As Exception
|
||||||
|
If ProcessException(eex, Token, $"ReparseMissing({url})",,, False) <> 1 Then Throw eex
|
||||||
|
End Try
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
Else
|
||||||
|
Throw New ArgumentException("Token is null", "Token")
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
ProcessException(ex, Token, "ReparseMissing error")
|
||||||
|
Finally
|
||||||
|
If rList.Count > 0 Then
|
||||||
|
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
|
||||||
|
rList.Clear()
|
||||||
|
End If
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "CreateFileFromUrl"
|
||||||
|
Protected Overloads Overrides Function CreateFileFromUrl(ByVal URL As String) As SFile
|
||||||
|
Return CreateFileFromUrl(URL, UTypes.Undefined)
|
||||||
|
End Function
|
||||||
|
Protected Overloads Function CreateFileFromUrl(ByVal URL As String, ByVal Type As UTypes) As SFile
|
||||||
|
Dim f As SFile = MyBase.CreateFileFromUrl(URL)
|
||||||
|
Dim force As Boolean = False
|
||||||
|
f.Separator = "\"
|
||||||
|
With URL.Split("/")
|
||||||
|
If .ListExists Then
|
||||||
|
With DirectCast(RegexReplace(.Last, RegEx_FilePattern), List(Of String))
|
||||||
|
If .ListExists(4) Then
|
||||||
|
f.Name = .Item(1).IfNullOrEmpty(f.Name)
|
||||||
|
f.Extension = .Item(3)
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
If Not f.Extension.IsEmptyString AndAlso f.Extension.ToLower = "m3u8" Then force = True : Type = UTypes.m3u8
|
||||||
|
If f.Extension.IsEmptyString Or force Then
|
||||||
|
Select Case Type
|
||||||
|
Case UTypes.Picture : f.Extension = "jpg"
|
||||||
|
Case UTypes.GIF : f.Extension = "gif"
|
||||||
|
Case UTypes.m3u8 : f.Name = "Video" : f.Extension = "mp4"
|
||||||
|
End Select
|
||||||
|
End If
|
||||||
|
Return f
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
#Region "DownloadContent"
|
||||||
|
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||||
|
DownloadContentDefault(Token)
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
||||||
|
Return M3U8.Download(URL, DestinationFile, Token, Progress, Not IsSingleObjectDownload)
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
#Region "DownloadSingleObject"
|
||||||
|
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
||||||
|
_TokenUpdateCount = 0
|
||||||
|
UpdateToken()
|
||||||
|
Dim l As List(Of String) = RegexReplace(Data.URL, RegEx_SinglePostPattern)
|
||||||
|
If l.ListExists(3) Then
|
||||||
|
NameTrue = l(1)
|
||||||
|
_ContentList.Add(New UserMedia(Data.URL) With {.State = UStates.Missing, .Post = l(2)})
|
||||||
|
ReparseMissing(Token)
|
||||||
|
End If
|
||||||
|
MyBase.DownloadSingleObject_GetPosts(Data, Token)
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Exception"
|
||||||
|
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
|
||||||
|
Optional ByVal EObj As Object = Nothing) As Integer
|
||||||
|
If Responser.StatusCode = Net.HttpStatusCode.BadRequest Then '400
|
||||||
|
If _TokenUpdateCount = 0 AndAlso UpdateToken(True) Then
|
||||||
|
Return 1
|
||||||
|
Else
|
||||||
|
Return 0
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
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
|
||||||