Compare commits
11 Commits
2023.3.5.0
...
2023.8.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df06a86651 | ||
|
|
bade8666d5 | ||
|
|
c70caa0035 | ||
|
|
ac532dbc6f | ||
|
|
82ef4f4410 | ||
|
|
d34414359c | ||
|
|
e51debc027 | ||
|
|
938042ea9e | ||
|
|
abdef81e5f | ||
|
|
e868c2e694 | ||
|
|
b2a9b22478 |
3
.gitattributes
vendored
@@ -1,2 +1,5 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
*.md text eol=crlf
|
||||
4
.github/FUNDING.yml
vendored
@@ -3,11 +3,11 @@
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: andyprogram
|
||||
ko_fi: #andyprogram
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: ['https://blockchair.com/bitcoin/address/BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET']
|
||||
custom: ['https://github.com/AAndyProgram/SCrawler/blob/main/HowToSupport.md']
|
||||
|
||||
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -13,11 +13,16 @@ A clear and concise description of what the bug is.
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. **Profile URL**:
|
||||
2. Do something
|
||||
3. See error
|
||||
2. **Post URL**:
|
||||
3. Do something
|
||||
4. See error
|
||||
|
||||
**Log data**
|
||||
If the program log contains any data.
|
||||
<details>
|
||||
<summary>Log data</summary>
|
||||
<pre>
|
||||
If the program log contains any data, replace this line with the log data. If the program log does not contain any data, write here about.
|
||||
</pre>
|
||||
</details>
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
@@ -25,11 +30,17 @@ A clear and concise description of what you expected to happen.
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Release information (please complete the following information):**
|
||||
- OS [e.g. Windows 10, Windows 11]
|
||||
- Architecture [e.g. x86, x64]
|
||||
- Version [e.g. 2.0.0.0]
|
||||
- NET.Framework version
|
||||
**Release information:**
|
||||
|
||||
**Please complete the following information or replace the following text with data 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 here).**
|
||||
- OS: [e.g. Windows 10, Windows 11]
|
||||
- Architecture: [e.g. x86, x64]
|
||||
- Version: [e.g. 2023.3.5.0]
|
||||
- NET.Framework version:
|
||||
- ffmpeg version (command `ffmpeg -version`):
|
||||
- yt-dlp version (command `yt-dlp --version`):
|
||||
- gallery-dl version (command `gallery-dl --version`):
|
||||
- cURL version (command `curl --version`):
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
7
.gitignore
vendored
@@ -9,8 +9,8 @@
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
ffmpeg.exe
|
||||
ToDo.txt
|
||||
.obsidian/
|
||||
BugReporterFormDiscordWebHook.vb
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
@@ -33,10 +33,7 @@ bld/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
ffmpeg/
|
||||
cURL/
|
||||
Info/
|
||||
Hidden/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
|
||||
@@ -8,20 +8,21 @@ I welcome requests! Follow these steps to contribute:
|
||||
1. If you have a code change suggestion, you can post a replacement code block. I also accept pull requests.
|
||||
|
||||
# How to build from source
|
||||
1. Delete the ```PersonalUtilities``` project from the solution.
|
||||
1. Delete the ```PersonalUtilities.Notifications``` project from the solution.
|
||||
1. Delete the ```cURL``` folder from the solution.
|
||||
1. Delete the ```ffmpeg.exe``` from the solution.
|
||||
1. Delete the `PersonalUtilities` project from the solution.
|
||||
1. Delete the `PersonalUtilities.Notifications` project from the solution.
|
||||
1. The following libraries must be added to project references with the '**Copy to output folder**' option:
|
||||
- ```PersonalUtilities.dll```
|
||||
- ```PersonalUtilities.Notifications.dll```
|
||||
- ```Microsoft.Toolkit.Uwp.Notifications.dll```
|
||||
- ```System.ValueTuple.dll```
|
||||
1. Import ```PersonalUtilities.Functions``` for the whole project.
|
||||
- `PersonalUtilities.dll`
|
||||
- `PersonalUtilities.Notifications.dll`
|
||||
- `Microsoft.Toolkit.Uwp.Notifications.dll`
|
||||
- `System.ValueTuple.dll`
|
||||
1. Import `PersonalUtilities.Functions` for the whole project.
|
||||
|
||||
**Always use the correct libraries. You must download libraries from the same release date as the code commit date.**
|
||||
|
||||
# How to request a new site
|
||||
|
||||
**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. 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).
|
||||
|
||||
|
||||
210
Changelog.md
@@ -1,3 +1,213 @@
|
||||
# 2023.8.6.0
|
||||
|
||||
*2023-08-06*
|
||||
|
||||
- Added
|
||||
- The ability to remove user data and/or download history for redownload
|
||||
- **Subscription** mode
|
||||
- Settings to change the program title and information in the program information
|
||||
- Settings for saving video thumbnail along with the file or in the cache (temporary cache or permanent cache)
|
||||
- A bug report form to create a bug report or say something nice to the developer :blush:
|
||||
- Prevent adding site-specific labels when adding to a collection
|
||||
- Ability to select custom user highlighting in the main window and feed.
|
||||
- Add a notification to the log if the user is not found on the site
|
||||
- Added visualization of users download queue
|
||||
- Ability to set more than one global paths
|
||||
- Improve user paths changing: now you can also simply move the user/collection to another global location
|
||||
- Ability to move multiple user/collection to another location
|
||||
- Download groups: added `Subscription` options
|
||||
- Download groups: the ability to set the number of users to download
|
||||
- Auto downloader: new group options
|
||||
- Auto downloader: additional skip options
|
||||
- Auto downloader: added force start
|
||||
- Feed: press `Ctrl+G` to go to a specific page
|
||||
- Feed: added site icon to post
|
||||
- Feed: always using `Friendly name` instead of `UserName` if it exists
|
||||
- Missing posts: the ability to delete all missing posts
|
||||
- Standalone downloader: add the ability to store download locations and quickly select after
|
||||
- Standalone downloader: add `Ctrl+O` hotkey to select destination path
|
||||
- Standalone downloader: add `Alt+O` hotkey to select destination path and save it to download locations
|
||||
- User editor: ability to hide/show site-specific labels in collection editing mode
|
||||
- Main window: filters by subscription and user
|
||||
- Instagram: if the user is not found on the site, SCrawler will check for a new user name
|
||||
- OnlyFans: handling of `504` and `429` errors
|
||||
- OnlyFans: the `sec-ch-ua` header is now optional
|
||||
- OnlyFans: ability to download 'Highlights" and media from chats
|
||||
- PathPlugin: incorrect detection of path existence
|
||||
- PornHub: completely rewritten videos parser
|
||||
- PornHub: now you choose which videos you want to download (uploaded, tagged, private, favorites)
|
||||
- PornHub: subscription mode
|
||||
- PornHub: ability to download search queries and search categories
|
||||
- Reddit: ability to set the number of concurrent downloads
|
||||
- Reddit: added bearer token (optional)
|
||||
- Reddit: added OAuth authorization (optional)
|
||||
- Reddit: options to use the bearer token for the timeline and/or saved posts
|
||||
- Reddit: option to disable the use of cookies for the timeline
|
||||
- ThisVid: now you can also download user's favorite videos
|
||||
- ThisVid: ability to download search queries, search categories and search tags
|
||||
- ThisVid: subscription mode
|
||||
- Twitter: new options: `Use the appropriate model`, `New endpoint: search`, `New endpoint: profiles`, `Abort on limit`, `Download already parsed` and `Media Model: allow non-user tweets`
|
||||
- Twitter: new user option `Force apply`
|
||||
- xHamster: ability to download search queries, search categories and search tags
|
||||
- xHamster: subscription mode
|
||||
- xHamster: pornstars download
|
||||
- XVideos: ability to download search queries, search categories and search tags
|
||||
- XVideos: subscription mode
|
||||
- YouTube: added `Output path: ask for a name` and `Output path: auto add` settings
|
||||
- YouTube: added the ability to store download locations and quickly select after
|
||||
- YouTube: subscription mode
|
||||
- Plugins.Attributes: added `DependentFields` attribute
|
||||
- Plugins.Attributes: replace `Dependencies` with `Arguments` (`PropertyUpdater` attribute)
|
||||
- Plugins.IPluginContentProvider: added `Options` and `IsSubscription` properties
|
||||
- Plugins.ISiteSettings: added `SubscriptionsAllowed` property
|
||||
- Plugins.ExchangeOptions: added `Options` field
|
||||
- Plugins: added `ExitException`
|
||||
- Other improvements
|
||||
- Updated
|
||||
- gallery-dl up to version 1.25.8
|
||||
- yt-dlp up to version 2023.07.06
|
||||
- LibVLCSharp up to 3.7.0
|
||||
- VideoLAN up to 3.0.18
|
||||
- Fixed
|
||||
- **TikTok** supported again!
|
||||
- Auto downloader: excluded labels and sites in default mode are not respected
|
||||
- Download info: does not remember the last size and location
|
||||
- Download info: hide unnecessary error
|
||||
- Feed: `webm` photos not showing
|
||||
- Search users: incorrect search by name
|
||||
- OnlyFans: incorrect parsing of username containing dots
|
||||
- OnlyFans: incorrect error handler
|
||||
- Reddit: Handling error 502 (Reddit data not downloading)
|
||||
- RedGifs: incorrect behavior when updating token
|
||||
- Twitter: gifs are not downloading
|
||||
- xHamster: some channels cannot be downloaded or are not fully downloaded
|
||||
- YouTube: re-saving elements when loading a video list
|
||||
- YouTube: files were not deleted when the delete button was clicked
|
||||
- YouTube: a bug that caused the video to redownload
|
||||
- Minor bugs
|
||||
|
||||
# 2023.6.19.0
|
||||
|
||||
*2023-06-19*
|
||||
|
||||
- Added
|
||||
- **OnlyFans**
|
||||
- YouTube: make the playlists parsing progress more informative
|
||||
- YouTube: add `Add` button to tray
|
||||
- YouTube: add `Ctrl+Click` on tray icon to add download
|
||||
- YouTube: add setting `Download on click in tray: show form`
|
||||
- Minor improvements to progress bars
|
||||
- Other improvements
|
||||
- Fixed
|
||||
- YouTube: incorrect sorting algorithm
|
||||
- LPSG: some files didn't download
|
||||
- Reddit: downloaded gifs are static (Issue #141)
|
||||
- xHamster: videos are not downloading or downloading incorrectly (Issue #144)
|
||||
- Progress bar bugs
|
||||
- Minor bugs
|
||||
|
||||
# 2023.6.9.0
|
||||
|
||||
*2023-06-09*
|
||||
|
||||
- Fixed
|
||||
- YouTube: opening paths to downloaded playlists and channels
|
||||
- Twitter: make the algorithm faster
|
||||
- Make progress more informative
|
||||
|
||||
# 2023.6.8.0
|
||||
|
||||
*2023-06-08*
|
||||
|
||||
- Added
|
||||
- YouTube: append artist name to music playlist output path
|
||||
- YouTube: save thumbnail path for playlist and channel
|
||||
- Fixed
|
||||
- YouTube: opening paths to downloaded playlists and channels
|
||||
- Twitter: profile not fully downloaded
|
||||
- Corrected form size for small monitors (Issue #136)
|
||||
|
||||
# 2023.6.5.0
|
||||
|
||||
*2023-06-05*
|
||||
|
||||
- Added
|
||||
- **Instagram**: add additional authorization headers
|
||||
- Setting to prevent user icon and banner from downloading (Request #129)
|
||||
- Add standalone downloader to tray context menu
|
||||
- YouTube downloader: added `Replace modification date` property
|
||||
- Minor improvements
|
||||
- Fixed
|
||||
- Fascist **Twitter**: posts not downloading (new API)
|
||||
- Main window: refill bug when the number of filtered profiles = 0
|
||||
- Standalone downloader: new items are not added to the queue
|
||||
- Standalone downloader: bug when not downloaded videos do not appear in the list when loading the program
|
||||
- Standalone downloader: add videos array not working
|
||||
- Saved posts: remove main progress perform when downloading saved posts
|
||||
- Minor bugs
|
||||
|
||||
# 2023.5.12.0
|
||||
|
||||
*2023-05-12*
|
||||
|
||||
- Added
|
||||
- Advanced progress (make progress bars more informative)
|
||||
- User metrics calculation
|
||||
- Reddit: improve parsing function
|
||||
- PornHub: add `Download UHD` option
|
||||
- Fixed
|
||||
- MD5 GIF hash bug
|
||||
- Mastodon: handle 'Forbidden' error
|
||||
- Mastodon: bug in parsing non-user posts
|
||||
- Pinterest: remove cookies requirement for saved posts
|
||||
- PornHub: resolutions issue
|
||||
- Reddit: missing & broken images bug
|
||||
- Main window: collection pointing bug
|
||||
|
||||
# 2023.4.28.0
|
||||
|
||||
*2023-04-28*
|
||||
|
||||
- Added
|
||||
- **YouTube**
|
||||
- **YouTube Music**
|
||||
- **Mastodon**
|
||||
- **Pinterest**
|
||||
- **ThisVid**
|
||||
- **YouTube downloader (standalone app)**
|
||||
- Redesigned standalone downloader and update environment
|
||||
- Added icons to download progress
|
||||
- Added icons to saved posts downloader
|
||||
- **Cookies**: new ways to add cookies. You can now export cookies using the browser extension and then import them into SCrawler!
|
||||
- User creation: ability to extract the user's URL from the buffer and apply parameters if found
|
||||
- User creation: simplified way to create new users (`Ctrl+Insert` to create a new user with default parameters from clipboard URL)
|
||||
- Ability to customize the placement of ffmpeg (and other) files
|
||||
- Ability to customize the command line encoding
|
||||
- New notification options for standalone downloader
|
||||
- Reddit: now it can download saved crossposts
|
||||
- RedGifs: added `UserAgent` option
|
||||
- Other improvements
|
||||
- Removed
|
||||
- User creation: remove the 'Channel' checkbox because it confuses people
|
||||
- Removed an ability to open SCrawler with `-v` argument
|
||||
- All ways to create users except URL. You can only properly create a user using the user's URL.
|
||||
- Plugins
|
||||
- Added `IDownloadableMedia` interface
|
||||
- Removed `Channel` option from all functions and enums
|
||||
- ISiteSettings: added `GetSingleMediaInstance` function
|
||||
- IPluginContentProvider: added `DownloadSingleObject` function
|
||||
- IPluginContentProvider: added tokens to `GetMedia` and `Download` functions
|
||||
- IPluginContentProvider: removed `GetSpecialData` function
|
||||
- UserMediaTypes: added `Audio` and `AudioPre` enums
|
||||
- Fixed
|
||||
- LPSG: attachments not downloading (Issue #114)
|
||||
- Twitter: saved posts not downloading (Issue #119)
|
||||
- XVIDEOS: saved posts not downloading
|
||||
- Deleting labels file
|
||||
- PornHub: hide unnecessary errors (Issue #116)
|
||||
- PornHub: photo galleries bug (Issue #115)
|
||||
- Minor bugs
|
||||
|
||||
# 2023.3.5.0
|
||||
|
||||
*2023-03-05*
|
||||
|
||||
21
FAQ.md
@@ -14,11 +14,7 @@ Any other questions I will keep in this file.
|
||||
|
||||
A: https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies
|
||||
|
||||
----
|
||||
|
||||
#### Q: **I can't copy cookies.**
|
||||
|
||||
A: Use the mouse. Don't use ```Ctrl+A```!
|
||||
<!---**ATTENTION! If you need to use cookies but cannot import them, I highly recommend that you don't use SCrawler and use another program. Don't create issues, discussions, or write to me on Discord. Any issue or discussion about cookies will be deleted immediately without a response. Any user who asks me about cookies on Discord will be banned.**--->
|
||||
|
||||
----
|
||||
|
||||
@@ -30,21 +26,22 @@ A: This is a GUI program.
|
||||
|
||||
#### Q: **Will CLI be added in the future?**
|
||||
|
||||
A: I do not think so.
|
||||
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)
|
||||
<!---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: **Twitter/Instagram download failed.**
|
||||
#### Q: **Site download failed.**
|
||||
|
||||
A: Check your credentials. Both of these sites require cookies. Check your [Twitter tokens](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-twitter-tokens) and [Instagram settings](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram). If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
|
||||
A: Check your credentials 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.
|
||||
|
||||
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||
**ATTENTION! Issues without URLs will be closed without a response!**
|
||||
|
||||
----
|
||||
|
||||
@@ -80,7 +77,7 @@ A: The program stored posts IDs in users' folders. For the first time, the progr
|
||||
|
||||
#### Q: **How to redownload all data**
|
||||
|
||||
A: Double-click on the user you want to redownload. In the opened window open folder setting. Delete the files ending with ```_Data.xml``` and ```_Posts.txt```. Download this user again.
|
||||
A: Double-click on the user you want to redownload. In the opened window open folder setting. Delete the files ending with ```_Data.xml``` and ```_Posts.txt```. Restart SCrawler. Download this user again.
|
||||
|
||||
----
|
||||
|
||||
@@ -116,4 +113,4 @@ A: I can only [suggest](#q-you-lost-me-your-program-is-too-complicated) you find
|
||||
|
||||
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
|
||||
|
||||
A: **NO**! I will not do it. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.
|
||||
A: **NO! NEVER!** 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.
|
||||
@@ -2,7 +2,6 @@ Your support is very valuable to me. Any support is greatly appreciated. Your su
|
||||
|
||||
You can support the program by:
|
||||
- **Bitcoin**: BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
|
||||
- :heavy_dollar_sign: make a donation on this site: https://ko-fi.com/andyprogram
|
||||
- :repeat: make a post about my program on your profile (Reddit, Twitter, Instagram and any other social networks)
|
||||
- :speech_balloon: tell your friends about the program
|
||||
- :heart: like the program on this site: https://alternativeto.net/software/scrawler/about/
|
||||
@@ -10,3 +9,4 @@ You can support the program by:
|
||||
- suggest my program as an alternative ([on this site](https://alternativeto.net/software/scrawler/about/)) to any program you have used before
|
||||
|
||||
I would be very grateful for any support! :blush:
|
||||
<!---:heavy_dollar_sign: make a donation on this site: https://ko-fi.com/andyprogram--->
|
||||
BIN
ProgramScreenshots/AppYouTube.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
ProgramScreenshots/AppYouTubeMusic.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
ProgramScreenshots/AppYouTubePlaylist.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
ProgramScreenshots/AppYouTubePlaylistParser.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
ProgramScreenshots/AppYouTubeSettings.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
ProgramScreenshots/AppYouTubeVideo.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
ProgramScreenshots/BugReport.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 483 KiB After Width: | Height: | Size: 491 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 11 KiB |
BIN
ProgramScreenshots/LocationsChanger.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 363 KiB After Width: | Height: | Size: 359 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
BIN
ProgramScreenshots/SettingsGlobalDownloader.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 19 KiB |
BIN
ProgramScreenshots/SettingsGlobalEnvironment.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 34 KiB |
BIN
ProgramScreenshots/SettingsSiteMastodon.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
ProgramScreenshots/SettingsSiteMastodonAdditional.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
ProgramScreenshots/SettingsSiteOnlyFans.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
ProgramScreenshots/SettingsSitePinterest.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 24 KiB |
BIN
ProgramScreenshots/SettingsSiteThisVid.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 22 KiB |
BIN
ProgramScreenshots/SettingsSiteYouTube.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 5.2 KiB |
BIN
ProgramScreenshots/UserDefaultQueryOptions.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
ProgramScreenshots/UserMetrics.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
@@ -1,6 +1,55 @@
|
||||
# yt-dlp
|
||||
|
||||
https://github.com/yt-dlp/yt-dlp/
|
||||
|
||||
**Great powerful CLI tool that supports hundreds of sites.**
|
||||
|
||||
SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare.
|
||||
|
||||
# 4K Video Downloader
|
||||
|
||||
https://www.4kdownload.com/-plbrz/video-downloader
|
||||
|
||||
| Option | SCrawler | 4K Stogram |
|
||||
| ---- | ---- | ---- |
|
||||
| User managament | **Advanced** | No |
|
||||
| Automatic downloads | **Yes** | No |
|
||||
| Downloading groups | **Yes** | No |
|
||||
| Labeling users | **Yes** | No |
|
||||
| Filtering | **Yes** | No |
|
||||
| Collections | **Yes** | No |
|
||||
| Specific user folders | **Yes** | No |
|
||||
| Favorite / Temporary user options | **Yes** | No |
|
||||
| Plugins support | **Yes** | No |
|
||||
| Download single video | **Unlimited** | 30 videos per day *(unlimited starts from 12 EUR)* |
|
||||
| Download videos per channel | **Unlimited** | 5 free *(unlimited starts from 12 EUR)* |
|
||||
| Download videos per playlist | **Unlimited** | 10 free *(unlimited starts from 12 EUR)* |
|
||||
| Download video subtitles | **Any for free**: single video, playlist, user/channel, album, etc| Free for single video |
|
||||
| The number of subtitles you can download for a video | **All of them** | Up to 10 |
|
||||
| Convert subtitles to additional formats | **Yes** | No |
|
||||
| Support LRC format | **Yes** | No |
|
||||
| Select audio codec for audio/video | **Yes** | No |
|
||||
| Extract and convert additional audio tracks for video | **Yes** | No |
|
||||
| Simultaneous downloads | **Unlimited** | 1 free, 3 for 12 EUR, 7 for 43 EUR|
|
||||
| Private YouTube content download | **Free** | Only in paid plans *starts from 12 EUR* |
|
||||
| **Paid** | **No** | Yes |
|
||||
| **Free options** | **The program is completely free** | Only **30** videos per day, 5 from a channel, 10 from a playlist |
|
||||
| Permitted Commercial Use | **Yes** | Starting from 43 EUR |
|
||||
| Automatic Subscriptions Update | **Free** | Paid (43 EUR) |
|
||||
| Posts and Captions Export | No | Paid (43 EUR) |
|
||||
| Advertisements free | **No ADs at all for free** | Paid (43 EUR) |
|
||||
| Operating Systems | Windows 10+ | Windows 7+, MacOS 10.13+, Ubuntu x64 |
|
||||
| Select want content type to download | **Yes** | No |
|
||||
| Instagram support | **Yes** | No |
|
||||
| Twitter support | **Yes** | No |
|
||||
| Reddit support | **Yes** | No |
|
||||
| Other sites support | **Yes** | No |
|
||||
| Still supported | Yes | Yes |
|
||||
|
||||
# 4K Stogram
|
||||
|
||||
https://www.4kdownload.com/products/product-stogram
|
||||
<!---https://www.4kdownload.com/products/product-stogram--->
|
||||
https://www.4kdownload.com/-ad0p9/stogram
|
||||
|
||||
| Option | SCrawler | 4K Stogram |
|
||||
| ---- | ---- | ---- |
|
||||
@@ -27,10 +76,10 @@ https://www.4kdownload.com/products/product-stogram
|
||||
| Export and import subscriptions | No | **Yes** |
|
||||
| **Paid** | **No** | Yes |
|
||||
| **Free options** | **The program is completely free** | Only **ONE** profile downloading and only **200 posts** per day |
|
||||
| Permitted Commercial Use | **Yes** | Starting from 43.56 EUR |
|
||||
| Automatic Subscriptions Update | **Free** | Paid (43.56 EUR) |
|
||||
| Posts and Captions Export | No | Paid (43.56 EUR) |
|
||||
| Advertisements free | **No ADs at all for free** | Paid (14.52) |
|
||||
| Permitted Commercial Use | **Yes** | Starting from 43 EUR |
|
||||
| Automatic Subscriptions Update | **Free** | Paid (43 EUR) |
|
||||
| Posts and Captions Export | No | Paid (43 EUR) |
|
||||
| Advertisements free | **No ADs at all for free** | Paid (18 EUR) |
|
||||
| Operating Systems | Windows 10+ | Windows 7+, MacOS 10.13+, Ubuntu x64 |
|
||||
| Select want content type to download | **Yes** | No |
|
||||
| Instagram support | Yes | Yes |
|
||||
@@ -68,7 +117,7 @@ https://github.com/RipMeApp/ripme
|
||||
| **Free options** | The program is completely free | The program is completely free, but site limits are not declared |
|
||||
| Operating Systems | Windows 10+ | Windows, MacOS, Linux |
|
||||
| Select want content type to download | Yes | Yes |
|
||||
| Suported sites | 9 internal and any site using plugins | 86+ sites (declared) |
|
||||
| Suported sites | 15+ internal and any site using plugins | 86+ sites (declared) |
|
||||
| Other sites support | **Yes** | No |
|
||||
| Still supported | **Yes** | **No (last release date May 4, 2021)** |
|
||||
|
||||
@@ -76,7 +125,6 @@ https://github.com/RipMeApp/ripme
|
||||
|
||||
https://github.com/mikf/gallery-dl
|
||||
|
||||
|
||||
**CLI tool**! Configured with JSON files only. Users need to learn complex configuration options, JSON, commands to use that tool. Very difficult to configure.
|
||||
**CLI tool**
|
||||
|
||||
SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare.
|
||||
98
README.md
@@ -1,3 +1,5 @@
|
||||
# :rainbow_flag: Happy LGBT Pride Month :tada:
|
||||
|
||||
# :rainbow_flag: Social networks crawler :rainbow_flag:
|
||||
|
||||
[](https://github.com/AAndyProgram/SCrawler/releases/latest)
|
||||
@@ -6,42 +8,53 @@
|
||||
[](FAQ.md)
|
||||
[](https://github.com/AAndyProgram/SCrawler/wiki)
|
||||
[](HowToSupport.md)
|
||||
:eu:
|
||||
:greece:
|
||||
|
||||
A program to download photo and video from [any site](#supported-sites) (e.g. Reddit, Twitter, Instagram, TikTok, RedGifs, PornHub, XHamster, XVIDEOS, LPSG).
|
||||
A program to download photo and video from [any site](#supported-sites) (e.g. YouTube, YouTube Music, OnlyFans, Reddit, Twitter, Mastodon, Instagram, TikTok, RedGifs, PornHub, XHamster, XVIDEOS, ThisVid, LPSG, Pinterest).
|
||||
|
||||
**If you like SCrawler, please like the program on [this site](https://alternativeto.net/software/scrawler/about/) and/or [this](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml)**
|
||||
|
||||
Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
|
||||
|
||||
[](https://ko-fi.com/andyprogram)
|
||||
|
||||
<!---Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
|
||||
[](https://ko-fi.com/andyprogram)--->
|
||||
**Bitcoin**: BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
|
||||
|
||||
[](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml#status)
|
||||
|
||||

|
||||

|
||||
|
||||
[**YouTube standalone application:**](https://github.com/AAndyProgram/SCrawler/wiki/YouTube-downloader)
|
||||
|
||||

|
||||
|
||||
# What can program do:
|
||||
- Download pictures and videos from users' profiles and subreddits:
|
||||
- YouTube videos, shorts, users, artists, playlists, music, tracks;
|
||||
- Reddit images, galleries of images, videos, saved posts;
|
||||
- Redgifs videos (https://www.redgifs.com/);
|
||||
- Twitter images and videos, saved (bookmarked) posts;
|
||||
- OnlyFans images and videos, saved (bookmarked) posts;
|
||||
- Mastodon images and videos, saved (bookmarked) posts;
|
||||
- Instagram images and videos, tagged posts, stories, saved posts;
|
||||
- TikTok videos ([limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits));
|
||||
- TikTok videos (*currently broken*; [limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits));
|
||||
- Pinterest boards, users, saved posts;
|
||||
- Imgur images, galleries and videos;
|
||||
- Gfycat videos;
|
||||
- PornHub images, videos, save (liked) posts;
|
||||
- XHamster images, videos, saved posts;
|
||||
- XVIDEOS videos;
|
||||
- PornHub images, videos, save (liked) posts, search queries, search categories;
|
||||
- XHamster images, videos, saved posts, search queries, search categories, search tags;
|
||||
- XVIDEOS videos, saved posts, search queries, search categories;
|
||||
- ThisVid images, videos, saved posts, search queries, search categories, search tags;
|
||||
- [Other](#supported-sites) supported sites
|
||||
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels)
|
||||
- Download [saved Reddit, Twitter and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
||||
- Parse [Reddit channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels)
|
||||
- Download [saved posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
||||
- Add users from parsed channel
|
||||
- **Advanced user management**
|
||||
- **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)
|
||||
- **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files and subscriptions posts)
|
||||
- Labeling users
|
||||
- Create [download groups](https://github.com/AAndyProgram/SCrawler/wiki/Settings#download-groups)
|
||||
- Adding users to favorites and temporary
|
||||
- Adding users and search queries in the **Subscription** mode (download post preview, but do not download the media file)
|
||||
- [Filter exists users](https://github.com/AAndyProgram/SCrawler/wiki#view) by label or group
|
||||
- Selection of media types you want to download (images only, videos only, both)
|
||||
- [Download a special video](https://github.com/AAndyProgram/SCrawler/wiki#download-separate-video), image or gallery
|
||||
@@ -52,18 +65,23 @@ Do you like this program? Consider adding to my coffee fund by making a donation
|
||||
- ...and many others...
|
||||
|
||||
# Supported sites
|
||||
|
||||
- **YouTube**
|
||||
- **YouTube Music**
|
||||
- **Reddit**
|
||||
- **Twitter**
|
||||
- **OnlyFans**
|
||||
- **Mastodon**
|
||||
- **Instagram**
|
||||
- **TikTok** ([limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits))
|
||||
- TikTok
|
||||
- RedGifs
|
||||
- Pinterest
|
||||
- Imgur
|
||||
- Gfycat
|
||||
- LPSG
|
||||
- **PornHub**
|
||||
- **XHamster**
|
||||
- **XVIDEOS**
|
||||
- **ThisVid**
|
||||
- [Other sites](Plugins.md)
|
||||
|
||||
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||
@@ -82,7 +100,8 @@ The program parses user posts and compares file names with existing ones to remo
|
||||
|
||||
## How to request a new site
|
||||
|
||||
Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
|
||||
<!---Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about--->
|
||||
**I'm currently not accepting requests to develop new sites.**
|
||||
|
||||
# Requirements
|
||||
|
||||
@@ -108,12 +127,17 @@ Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
|
||||
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||
- [Reddit](https://github.com/AAndyProgram/SCrawler/wiki/Settings#reddit)
|
||||
- [Twitter](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter)
|
||||
- [OnlyFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans)
|
||||
- [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Mastodon)
|
||||
- [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram)
|
||||
- [TikTok](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok)
|
||||
- [RedGifs](https://github.com/AAndyProgram/SCrawler/wiki/Settings#redgifs)
|
||||
- [YouTube](https://github.com/AAndyProgram/SCrawler/wiki/Settings#YouTube)
|
||||
- [Pinterest](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Pinterest)
|
||||
- [PornHub](https://github.com/AAndyProgram/SCrawler/wiki/Settings#pornhub)
|
||||
- [XHamster](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xhamster)
|
||||
- [XVIDEOS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xvideos)
|
||||
- [ThisVid](https://github.com/AAndyProgram/SCrawler/wiki/Settings#ThisVid)
|
||||
- [LPSG](https://github.com/AAndyProgram/SCrawler/wiki/Settings#lpsg)
|
||||
|
||||
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**
|
||||
@@ -142,20 +166,40 @@ The program has an intuitive interface.
|
||||
|
||||
Just add a user profile and **click the ```Download``` button**.
|
||||
|
||||
Read more about adding users and subreddits [here](https://github.com/AAndyProgram/SCrawler/wiki/Users)
|
||||
```mermaid
|
||||
stateDiagram
|
||||
Start: Add site credentials
|
||||
What: What would I like to do
|
||||
DownUser: Download user
|
||||
DownVideo: Download video
|
||||
AUser: Add user (1)
|
||||
OVIF: Open standalone downloader (2)
|
||||
AVideo: Add video url
|
||||
F5: Press 'F5' or click the download button
|
||||
[*]-->Start
|
||||
Start-->What
|
||||
What-->DownUser
|
||||
What-->DownVideo
|
||||
DownUser-->AUser
|
||||
DownVideo-->OVIF
|
||||
OVIF-->AVideo
|
||||
AVideo-->F5
|
||||
AUser-->F5
|
||||
F5-->[*]
|
||||
```
|
||||
1. Press `Insert` or click the `Download` button ([read more here](https://github.com/AAndyProgram/SCrawler/wiki#users-list), [hot keys](https://github.com/AAndyProgram/SCrawler/wiki#hot-keys))
|
||||
2. Click the `Download` button, then `Standalone downloader` ([read more here](https://github.com/AAndyProgram/SCrawler/wiki#download-separate-video))
|
||||
|
||||

|
||||
|
||||
# Using program as just video downloader
|
||||
|
||||
Create a shortcut for the program. Open shortcut properties. In the ```Shortcut``` tab, in the ```Target``` field, just add the letter ```v``` at the end across the space.
|
||||
|
||||
Example: ```D:\Programs\SCrawler\SCrawler.exe v```
|
||||
|
||||

|
||||
|
||||
# Contact me
|
||||
|
||||
[](https://matrix.to/#/@andyprogram:matrix.org)
|
||||
[e-mail](mailto:andyprogram@proton.me): andyprogram@proton.me
|
||||
|
||||
[](https://discordapp.com/users/1012768226679206009) AndyProgram#3804
|
||||
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
|
||||
|
||||
@@ -44,6 +44,16 @@ Namespace Plugin.Attributes
|
||||
Name = PropertyName
|
||||
End Sub
|
||||
End Class
|
||||
''' <summary>Set the dependent fields that need to be updated when this property is changed internally.</summary>
|
||||
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class DependentFields : Inherits Attribute
|
||||
Public ReadOnly Fields As String()
|
||||
Public Sub New(ByVal Field As String)
|
||||
Fields = {Field}
|
||||
End Sub
|
||||
Public Sub New(ByVal Fields As String())
|
||||
Me.Fields = Fields
|
||||
End Sub
|
||||
End Class
|
||||
''' <summary>Store property value in settings XML file</summary>
|
||||
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class PXML : Inherits Attribute
|
||||
Public ReadOnly ElementName As String
|
||||
@@ -59,16 +69,16 @@ Namespace Plugin.Attributes
|
||||
''' <summary>Special property updater</summary>
|
||||
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=True, Inherited:=False)> Public NotInheritable Class PropertyUpdater : Inherits Attribute
|
||||
Public ReadOnly Name As String
|
||||
Public ReadOnly Dependencies As String()
|
||||
Public ReadOnly Arguments As String()
|
||||
''' <inheritdoc cref="PropertyUpdater.New(String, String())"/>
|
||||
Public Sub New(ByVal UpdatingPropertyName As String)
|
||||
Name = UpdatingPropertyName
|
||||
End Sub
|
||||
''' <summary>Initialize a new PropertyUpdater attribute</summary>
|
||||
''' <param name="UpdatingPropertyName">The name of the property to be updated</param>
|
||||
Public Sub New(ByVal UpdatingPropertyName As String, ByVal Dependent As String())
|
||||
Public Sub New(ByVal UpdatingPropertyName As String, ByVal Arguments As String())
|
||||
Name = UpdatingPropertyName
|
||||
Dependencies = Dependent
|
||||
Me.Arguments = Arguments
|
||||
End Sub
|
||||
End Class
|
||||
''' <summary>Plugin key</summary>
|
||||
|
||||
34
SCrawler.PluginProvider/Interfaces/IDownloadableMedia.vb
Normal file
@@ -0,0 +1,34 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace Plugin
|
||||
Public Interface IDownloadableMedia : Inherits IUserMedia, IDisposable
|
||||
Event CheckedChange As EventHandler
|
||||
Event ThumbnailChanged As EventHandler
|
||||
Event StateChanged As EventHandler
|
||||
ReadOnly Property SiteIcon As Drawing.Image
|
||||
ReadOnly Property Site As String
|
||||
ReadOnly Property SiteKey As String
|
||||
Property ThumbnailUrl As String
|
||||
Property ThumbnailFile As String
|
||||
Property Title As String
|
||||
Property Size As Integer
|
||||
Property Duration As TimeSpan
|
||||
Property Progress As Object
|
||||
ReadOnly Property HasError As Boolean
|
||||
ReadOnly Property Exists As Boolean
|
||||
Property Checked As Boolean
|
||||
Property Instance As IPluginContentProvider
|
||||
Sub Download(ByVal UseCookies As Boolean, ByVal Token As Threading.CancellationToken)
|
||||
Sub Delete(ByVal RemoveFiles As Boolean)
|
||||
Sub Load(ByVal File As String)
|
||||
Sub Save()
|
||||
Overloads Function ToString() As String
|
||||
Overloads Function ToString(ByVal ForMediaItem As Boolean) As String
|
||||
End Interface
|
||||
End Namespace
|
||||
@@ -8,13 +8,16 @@
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace Plugin
|
||||
Public Interface IPluginContentProvider : Inherits IDisposable
|
||||
Event ProgressChanged(ByVal Count As Integer)
|
||||
Event TotalCountChanged(ByVal Count As Integer)
|
||||
Event ProgressChanged(ByVal Value As Integer)
|
||||
Event ProgressMaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
|
||||
Event ProgressPreChanged As ProgressChangedEventHandler
|
||||
Event ProgressPreMaximumChanged As ProgressMaximumChangedEventHandler
|
||||
Property Thrower As IThrower
|
||||
Property LogProvider As ILogProvider
|
||||
Property Settings As ISiteSettings
|
||||
Property Name As String
|
||||
Property ID As String
|
||||
Property Options As String
|
||||
Property ParseUserMediaOnly As Boolean
|
||||
Property UserDescription As String
|
||||
Property ExistingContentList As List(Of IUserMedia)
|
||||
@@ -23,6 +26,7 @@ Namespace Plugin
|
||||
Property UserExists As Boolean
|
||||
Property UserSuspended As Boolean
|
||||
Property IsSavedPosts As Boolean
|
||||
Property IsSubscription As Boolean
|
||||
Property SeparateVideoFolder As Boolean
|
||||
Property DataPath As String
|
||||
Property PostsNumberLimit As Integer?
|
||||
@@ -32,7 +36,8 @@ Namespace Plugin
|
||||
Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
Sub XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String)))
|
||||
Function XmlFieldsGet() As List(Of KeyValuePair(Of String, String))
|
||||
Sub GetMedia()
|
||||
Sub Download()
|
||||
Sub GetMedia(ByVal Token As Threading.CancellationToken)
|
||||
Sub Download(ByVal Token As Threading.CancellationToken)
|
||||
Sub DownloadSingleObject(ByVal Data As IDownloadableMedia, ByVal Token As Threading.CancellationToken)
|
||||
End Interface
|
||||
End Namespace
|
||||
@@ -12,17 +12,18 @@ Namespace Plugin
|
||||
Enum Download As Integer
|
||||
Main = 0
|
||||
SavedPosts = 1
|
||||
Channel = 2
|
||||
SingleObject = 2
|
||||
End Enum
|
||||
ReadOnly Property Icon As Icon
|
||||
ReadOnly Property Image As Image
|
||||
ReadOnly Property Site As String
|
||||
ReadOnly Property SubscriptionsAllowed As Boolean
|
||||
Property Logger As ILogProvider
|
||||
Function GetUserUrl(ByVal User As IPluginContentProvider, ByVal Channel As Boolean) As String
|
||||
Function GetUserUrl(ByVal User As IPluginContentProvider) As String
|
||||
Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
|
||||
Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
|
||||
Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable
|
||||
Function GetInstance(ByVal What As Download) As IPluginContentProvider
|
||||
Function GetSingleMediaInstance(ByVal URL As String, ByVal OutputFile As String) As IDownloadableMedia
|
||||
Function GetUserPostUrl(ByVal User As IPluginContentProvider, ByVal Media As IUserMedia) As String
|
||||
#Region "XML Support"
|
||||
Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String)))
|
||||
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2023.2.5.0")>
|
||||
<Assembly: AssemblyFileVersion("2023.2.5.0")>
|
||||
<Assembly: AssemblyVersion("2023.8.6.0")>
|
||||
<Assembly: AssemblyFileVersion("2023.8.6.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
@@ -11,15 +11,12 @@ Namespace Plugin
|
||||
Public UserName As String
|
||||
Public SiteName As String
|
||||
Public HostKey As String
|
||||
Public IsChannel As Boolean
|
||||
Public Options As String
|
||||
Public Exists As Boolean
|
||||
Public Sub New(ByVal Site As String, ByVal Name As String)
|
||||
UserName = Name
|
||||
SiteName = Site
|
||||
End Sub
|
||||
Public Sub New(ByVal Site As String, ByVal Name As String, ByVal IsChannel As Boolean)
|
||||
Me.New(Site, Name)
|
||||
Me.IsChannel = IsChannel
|
||||
Exists = Not String.IsNullOrEmpty(Name) And Not String.IsNullOrWhiteSpace(Name)
|
||||
End Sub
|
||||
End Structure
|
||||
End Namespace
|
||||
36
SCrawler.PluginProvider/Objects/ExitException.vb
Normal file
@@ -0,0 +1,36 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace Plugin
|
||||
''' <summary>Represents errors that occur during downloading to be thrown to the root downloading function.</summary>
|
||||
Public Class ExitException : Inherits Exception
|
||||
''' <summary>Add only the message to the log, without adding a <see cref="StackTrace"/>. Default: <see langword="True"/>.</summary>
|
||||
''' <returns><see langword="True"/> if only the message should be added to the log; otherwise the stack trace will also be added.</returns>
|
||||
Public Property SimpleLogLine As Boolean = True
|
||||
''' <summary>Don't add a message to the log. Default: <see langword="False"/>.</summary>
|
||||
''' <returns><see langword="True"/> if the error is exit-only and there is no need to add a message to the log; otherwise add a message to the log.</returns>
|
||||
Public Property Silent As Boolean = False
|
||||
''' <summary>Initializes a new instance of the <see cref="ExitException"/> class.</summary>
|
||||
Public Sub New()
|
||||
End Sub
|
||||
''' <summary>Initializes a new instance of the <see cref="ExitException"/> class with a specified error message.</summary>
|
||||
''' <param name="Message">The message that describes the error.</param>
|
||||
Public Sub New(ByVal Message As String)
|
||||
MyBase.New(Message)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Initializes a new instance of the <see cref="ExitException"/> class with a specified error message
|
||||
''' and a reference to the inner exception that is the cause of this exception.
|
||||
''' </summary>
|
||||
''' <param name="Message">The error message that explains the reason for the exception.</param>
|
||||
''' <param name="InnerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
Public Sub New(ByVal Message As String, ByVal InnerException As Exception)
|
||||
MyBase.New(Message, InnerException)
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -7,12 +7,15 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace Plugin
|
||||
Public Delegate Sub ProgressChange(ByVal Value As Double?, ByVal Maximum As Double?, ByVal Information As String)
|
||||
Public Enum UserMediaTypes As Integer
|
||||
Undefined = 0
|
||||
[Picture] = 1
|
||||
[Video] = 2
|
||||
[Text] = 3
|
||||
Picture = 1
|
||||
Video = 2
|
||||
Audio = 200
|
||||
Text = 4
|
||||
VideoPre = 10
|
||||
AudioPre = 215
|
||||
GIF = 50
|
||||
m3u8 = 100
|
||||
End Enum
|
||||
@@ -24,12 +27,12 @@ Namespace Plugin
|
||||
Missing = 4
|
||||
End Enum
|
||||
Public Structure PluginUserMedia : Implements IUserMedia
|
||||
Public Property ContentType As Integer Implements IUserMedia.ContentType
|
||||
Public Property ContentType As UserMediaTypes Implements IUserMedia.ContentType
|
||||
Public Property URL As String Implements IUserMedia.URL
|
||||
Public Property URL_BASE As String Implements IUserMedia.URL_BASE
|
||||
Public Property MD5 As String Implements IUserMedia.MD5
|
||||
Public Property File As String Implements IUserMedia.File
|
||||
Public Property DownloadState As Integer Implements IUserMedia.DownloadState
|
||||
Public Property DownloadState As UserMediaStates Implements IUserMedia.DownloadState
|
||||
Public Property PostID As String Implements IUserMedia.PostID
|
||||
Public Property PostDate As Date? Implements IUserMedia.PostDate
|
||||
Public Property SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||
@@ -37,12 +40,12 @@ Namespace Plugin
|
||||
Public Property [Object] As Object Implements IUserMedia.Object
|
||||
End Structure
|
||||
Public Interface IUserMedia
|
||||
Property ContentType As Integer
|
||||
Property ContentType As UserMediaTypes
|
||||
Property URL As String
|
||||
Property URL_BASE As String
|
||||
Property MD5 As String
|
||||
Property File As String
|
||||
Property DownloadState As Integer
|
||||
Property DownloadState As UserMediaStates
|
||||
Property PostID As String
|
||||
Property PostDate As Date?
|
||||
Property SpecialFolder As String
|
||||
|
||||
@@ -102,10 +102,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Attributes\Attributes.vb" />
|
||||
<Compile Include="Interfaces\IDownloadableMedia.vb" />
|
||||
<Compile Include="ObjectInterfaces\IPropertyProvider.vb" />
|
||||
<Compile Include="Objects\ExchangeOptions.vb" />
|
||||
<Compile Include="ObjectInterfaces\ILogProvider.vb" />
|
||||
<Compile Include="Interfaces\IPluginContentProvider.vb" />
|
||||
<Compile Include="Objects\ExitException.vb" />
|
||||
<Compile Include="Objects\PluginUserMedia.vb" />
|
||||
<Compile Include="Interfaces\ISiteSettings.vb" />
|
||||
<Compile Include="ObjectInterfaces\IThrower.vb" />
|
||||
|
||||
3
SCrawler.YouTube/.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
||||
[*.vb]
|
||||
# Modifier preferences
|
||||
file_header_template = Copyright (C) 2023 Andy https://github.com/AAndyProgram\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
6
SCrawler.YouTube/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||
</startup>
|
||||
</configuration>
|
||||
30
SCrawler.YouTube/Attributes/GridVisibleAttribute.vb
Normal file
@@ -0,0 +1,30 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Attributes
|
||||
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
|
||||
Public Class GridVisibleAttribute : Inherits Attribute
|
||||
Private ReadOnly NonAppMode As Boolean = True
|
||||
Public Sub New()
|
||||
End Sub
|
||||
Public Sub New(ByVal NonAppMode As Boolean)
|
||||
Me.NonAppMode = NonAppMode
|
||||
End Sub
|
||||
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is GridVisibleAttribute Then
|
||||
If NonAppMode Then
|
||||
Return DirectCast(Obj, GridVisibleAttribute).NonAppMode
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
81
SCrawler.YouTube/Base/Structures.vb
Normal file
@@ -0,0 +1,81 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Base
|
||||
Public Structure Thumbnail : Implements IIndexable, IComparable(Of Thumbnail)
|
||||
Public ID As String
|
||||
Public Width As Integer
|
||||
Public Height As Integer
|
||||
Public URL As String
|
||||
Public Property Index As Integer Implements IIndexable.Index
|
||||
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
|
||||
Dim t As Thumbnail = Obj
|
||||
t.Index = Index
|
||||
Return t
|
||||
End Function
|
||||
Private Function CompareTo(ByVal Other As Thumbnail) As Integer Implements IComparable(Of Thumbnail).CompareTo
|
||||
Return Width.CompareTo(Other.Width) * -1
|
||||
End Function
|
||||
End Structure
|
||||
Public Structure Subtitles : Implements IIndexable, IComparable(Of Subtitles)
|
||||
Public ID As String
|
||||
Public Name As String
|
||||
Public Formats As String
|
||||
Public ReadOnly Property FullID As String
|
||||
Get
|
||||
Return IIf(ID = "en", "en.*", ID)
|
||||
End Get
|
||||
End Property
|
||||
Public Property Index As Integer Implements IIndexable.Index
|
||||
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
|
||||
Dim s As Subtitles = Obj
|
||||
s.Index = Index
|
||||
Return s
|
||||
End Function
|
||||
Private Function CompareTo(ByVal Other As Subtitles) As Integer Implements IComparable(Of Subtitles).CompareTo
|
||||
Return Name.CompareTo(Other.Name)
|
||||
End Function
|
||||
End Structure
|
||||
Public Enum YouTubeMediaType As Integer
|
||||
Undefined = 0
|
||||
[Single] = 1
|
||||
Channel = 2
|
||||
PlayList = 3
|
||||
End Enum
|
||||
Public Structure MediaObject : Implements IIndexable, IComparable(Of MediaObject)
|
||||
Public Type As Plugin.UserMediaTypes
|
||||
Public ID As String
|
||||
Public Extension As String
|
||||
Public Width As Integer
|
||||
Public Height As Integer
|
||||
Public FPS As Integer
|
||||
Public Bitrate As Integer
|
||||
''' <summary>Kb</summary>
|
||||
Public Size As Double
|
||||
Public Codec As String
|
||||
Public Protocol As String
|
||||
Public URL As String
|
||||
Public Property Index As Integer Implements IIndexable.Index
|
||||
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
|
||||
Dim m As MediaObject = Obj
|
||||
m.Index = Index
|
||||
Return m
|
||||
End Function
|
||||
Private Function CompareTo(ByVal Other As MediaObject) As Integer Implements IComparable(Of MediaObject).CompareTo
|
||||
If Type = Other.Type Then
|
||||
If Width.CompareTo(Other.Width) = 0 Then
|
||||
Return Size.CompareTo(Other.Size) * -1
|
||||
Else
|
||||
Return Width.CompareTo(Other.Width) * -1
|
||||
End If
|
||||
Else
|
||||
Return CInt(Type).CompareTo(CInt(Other.Type))
|
||||
End If
|
||||
End Function
|
||||
End Structure
|
||||
End Namespace
|
||||
38
SCrawler.YouTube/Base/TableControlsProcessor.vb
Normal file
@@ -0,0 +1,38 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class TableControlsProcessor
|
||||
Private ReadOnly Property TP_CONTROLS As TableLayoutPanel
|
||||
Friend Sub New(ByRef TP As TableLayoutPanel)
|
||||
TP_CONTROLS = TP
|
||||
End Sub
|
||||
Private _LatestSelected As Integer = -1
|
||||
Friend Sub MediaItem_Click(ByVal Sender As Object, ByVal e As EventArgs)
|
||||
Try
|
||||
_LatestSelected = TP_CONTROLS.GetPositionFromControl(Sender).Row
|
||||
DirectCast(Sender, Control).Focus()
|
||||
Catch ex As Exception
|
||||
_LatestSelected = -1
|
||||
End Try
|
||||
End Sub
|
||||
Friend Sub MediaItem_KeyDown(ByVal Sender As Object, ByVal e As KeyEventArgs)
|
||||
Try
|
||||
If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
|
||||
Dim newPosition% = _LatestSelected + IIf(e.KeyCode = Keys.Down, 1, -1)
|
||||
If newPosition < 0 Then newPosition = 0
|
||||
If newPosition <> _LatestSelected Then
|
||||
Dim cnt As DownloadObjects.STDownloader.MediaItem = TP_CONTROLS.GetControlFromPosition(0, newPosition)
|
||||
If Not cnt Is Nothing Then cnt.PerformClick()
|
||||
End If
|
||||
End If
|
||||
Catch
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
165
SCrawler.YouTube/Base/YouTubeFunctions.vb
Normal file
@@ -0,0 +1,165 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Namespace API.YouTube.Base
|
||||
Public NotInheritable Class YouTubeFunctions
|
||||
Public Const YouTubeCachePathRoot As String = "_CacheYouTube\"
|
||||
Public Const UserChannelOption As String = "channel"
|
||||
Public Const TrueUrlPattern As String = "https?://[^/]*?youtube.com/[^\?/&]+((\??[^\?/&]+|/[^\?/&]+))"
|
||||
'2 - type; 5 - id
|
||||
Public Const UrlTypePattern As String = "(?<=https?://[^/]*?youtube.com/)((@|[^\?/&]+))([/\?]{0,1}(list=|v=|)([^\?/&]*))(?=(\S+|\Z|))"
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Public Shared Function IsMyUrl(ByVal URL As String) As Boolean
|
||||
Return Not Info_GetUrlType(URL) = YouTubeMediaType.Undefined
|
||||
End Function
|
||||
Public Shared Function Info_GetUrlType(ByVal URL As String, Optional ByRef IsMusic As Boolean = False,
|
||||
Optional ByRef IsChannelUser As Boolean = False, Optional ByRef Id As String = Nothing) As YouTubeMediaType
|
||||
If Not URL.IsEmptyString Then
|
||||
IsMusic = URL.Contains("music.youtube.com")
|
||||
IsChannelUser = False
|
||||
Dim data As List(Of String) = RegexReplace(URL, RParams.DMS(UrlTypePattern, 0, RegexReturn.ListByMatch, EDP.ReturnValue))
|
||||
If data.ListExists Then
|
||||
If data.Count >= 6 Then Id = data(5)
|
||||
If data.Count >= 3 And Not data(2).IsEmptyString Then
|
||||
Select Case data(2).ToLower
|
||||
Case "watch" : Return YouTubeMediaType.Single
|
||||
Case "playlist" : Return YouTubeMediaType.PlayList
|
||||
Case UserChannelOption, "@" : IsChannelUser = data(2).ToLower = UserChannelOption : Return YouTubeMediaType.Channel
|
||||
End Select
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Return YouTubeMediaType.Undefined
|
||||
End Function
|
||||
''' <summary>'--no-cookies-from-browser --cookies CookiesFile'</summary>
|
||||
Public Shared Function GetCookiesCommand(ByVal UseCookies As Boolean, ByVal CookiesFile As SFile) As String
|
||||
If UseCookies And CookiesFile.Exists Then
|
||||
Return $"--no-cookies-from-browser --cookies ""{CookiesFile}"""
|
||||
Else
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
''' <param name="DateAfter">Data with upload date 'more than or equal to' date will be downloaded</param>
|
||||
''' <param name="DateBefore">Data with upload date 'less than or equal to' date will be downloaded</param>
|
||||
''' <exception cref="ArgumentNullException"></exception>
|
||||
''' <exception cref="IO.FileNotFoundException"></exception>
|
||||
''' <exception cref="InvalidOperationException"></exception>
|
||||
Public Shared Function Parse(ByVal URL As String, Optional ByVal UseCookies As Boolean? = Nothing,
|
||||
Optional ByVal Token As Threading.CancellationToken = Nothing, Optional ByVal Progress As IMyProgress = Nothing,
|
||||
Optional ByVal GetDefault As Boolean? = Nothing, Optional ByVal GetShorts As Boolean? = Nothing,
|
||||
Optional ByVal DateAfter As Date? = Nothing, Optional ByVal DateBefore As Date? = Nothing) As IYouTubeMediaContainer
|
||||
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)
|
||||
Dim urlOrig$ = URL
|
||||
URL = RegexReplace(URL, TrueUrlRegEx)
|
||||
If URL.IsEmptyString Then Throw New ArgumentNullException("URL", $"Can't get true URL from [{urlOrig}]")
|
||||
Dim isMusic As Boolean = False
|
||||
Dim objType As YouTubeMediaType = Info_GetUrlType(URL, isMusic)
|
||||
If Not objType = YouTubeMediaType.Undefined Then
|
||||
Dim __GetDefault As Boolean = If(GetDefault, True)
|
||||
Dim __GetShorts As Boolean = If(GetShorts, True)
|
||||
If isMusic Then __GetShorts = False
|
||||
Dim container As IYouTubeMediaContainer
|
||||
Dim pattern$ = "%(channel_id)s_%(id)s_%(playlist_index)s"
|
||||
|
||||
Select Case objType
|
||||
Case YouTubeMediaType.Single
|
||||
__GetShorts = False
|
||||
If isMusic Then container = New Track Else container = New Video
|
||||
Case YouTubeMediaType.PlayList : container = New PlayList : pattern = "%(playlist_index)s_%(id)s" : __GetShorts = False
|
||||
Case YouTubeMediaType.Channel
|
||||
container = New Channel
|
||||
If isMusic Then pattern = "%(playlist_id)s/%(channel_id)s_%(id)s_%(playlist_index)s"
|
||||
Case Else : Throw New InvalidOperationException($"Type '{objType}' is not supported by YouTubeDownloader")
|
||||
End Select
|
||||
|
||||
If UseCookies.HasValue Then container.UseCookies = UseCookies.Value
|
||||
Dim result As Boolean = False
|
||||
Dim cookiesExists As Boolean = YouTubeCookieNetscapeFile.Exists
|
||||
Dim _CachePathDefault As SFile = MyCache.NewPath(, EDP.ReturnValue)
|
||||
If _CachePathDefault.IsEmptyString Then _CachePathDefault = $"{YouTubeCachePathRoot}{SFile.GetDirectories(YouTubeCachePathRoot,,, EDP.ReturnValue).Count + 1}"
|
||||
_CachePathDefault.Exists(SFO.Path, True, EDP.ThrowException)
|
||||
pattern = $"{_CachePathDefault.PathWithSeparator}{pattern}"
|
||||
|
||||
Dim withCookieRequested As Boolean = False
|
||||
Dim useCookiesForce As Boolean = UseCookies.HasValue AndAlso UseCookies.Value AndAlso cookiesExists
|
||||
If UseCookies.HasValue AndAlso UseCookies.Value Then
|
||||
withCookieRequested = True
|
||||
result = Parse_Internal(URL, pattern, _CachePathDefault, True, YouTubeCookieNetscapeFile, DateAfter, DateBefore, __GetDefault, __GetShorts)
|
||||
End If
|
||||
If Not result And Not withCookieRequested Then
|
||||
If Not UseCookies.HasValue OrElse Not UseCookies.Value Then result = Parse_Internal(URL, pattern, _CachePathDefault, False, YouTubeCookieNetscapeFile, DateAfter, DateBefore, __GetDefault, __GetShorts)
|
||||
If Not result And Not UseCookies.HasValue And cookiesExists Then result = Parse_Internal(URL, pattern, _CachePathDefault, True, YouTubeCookieNetscapeFile, DateAfter, DateBefore, __GetDefault, __GetShorts)
|
||||
End If
|
||||
|
||||
If result Then
|
||||
container.Parse(Nothing, _CachePathDefault, isMusic, Token, Progress)
|
||||
If Not container.HasError Then container.URL = URL : Return container
|
||||
End If
|
||||
container.Dispose()
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
Private Shared Function Parse_Internal(ByVal URL As String, ByVal OutputPattern As String, ByVal OutputPath As SFile,
|
||||
ByVal UseCookies As Boolean, ByVal CookiesFile As SFile,
|
||||
ByVal DateAfter As Date?, ByVal DateBefore As Date?,
|
||||
ByVal GetDefault As Boolean, ByVal GetShorts As Boolean) As Boolean
|
||||
Try
|
||||
Dim command$ = "yt-dlp --write-info-json --skip-download"
|
||||
command.StringAppend(GetCookiesCommand(UseCookies, CookiesFile), " ")
|
||||
If DateAfter.HasValue Then command.StringAppend($"--dateafter {DateAfter.Value:yyyyMMdd}", " ")
|
||||
If DateBefore.HasValue Then command.StringAppend($"--datebefore {DateBefore.Value:yyyyMMdd}", " ")
|
||||
command.StringAppend("{0}" & $" -o ""{OutputPattern}""", " ")
|
||||
#If DEBUG Then
|
||||
Debug.WriteLine(String.Format(command, URL))
|
||||
#End If
|
||||
Using batch As New BatchExecutor(True)
|
||||
With batch
|
||||
.CommandPermanent = BatchExecutor.GetDirectoryCommand(MyYouTubeSettings.YTDLP.Value)
|
||||
If GetDefault Then .Execute(String.Format(command, URL))
|
||||
If GetShorts Then .Execute(String.Format(command, $"{URL.StringTrimEnd("/")}/shorts"))
|
||||
End With
|
||||
End Using
|
||||
Return SFile.GetFiles(OutputPath,, IO.SearchOption.AllDirectories, EDP.ReturnValue).Count > 0
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex,
|
||||
$"[API.YouTube.Base.YouTubeFunctions.Parse_Internal({URL}, {UseCookies})]", False)
|
||||
End Try
|
||||
End Function
|
||||
Friend Shared Function CreateContainer(ByVal f As SFile) As IYouTubeMediaContainer
|
||||
Dim c As IYouTubeMediaContainer = Nothing
|
||||
If f.Exists(SFO.File, False) Then
|
||||
Using x As New XmlFile(f, Protector.Modes.All, False) With {.AllowSameNames = True, .XmlReadOnly = True}
|
||||
x.LoadData()
|
||||
If x.Value(YouTubeMediaContainerBase.Name_SiteKey) = YouTubeSiteKey Then
|
||||
Select Case x.Value(YouTubeMediaContainerBase.Name_ObjectType).FromXML(Of Integer)(YouTubeMediaType.Undefined)
|
||||
Case YouTubeMediaType.Channel : c = New Channel
|
||||
Case YouTubeMediaType.PlayList : c = New PlayList
|
||||
Case YouTubeMediaType.Single
|
||||
If x.Value(YouTubeMediaContainerBase.Name_IsMusic).FromXML(Of Boolean)(False) Then
|
||||
c = New Track
|
||||
Else
|
||||
c = New Video
|
||||
End If
|
||||
Case Else : Throw New ArgumentException($"Object type '{x.Value(YouTubeMediaContainerBase.Name_ObjectType)}' is not identified",
|
||||
"ObjectType") With {.HelpLink = NameOf(CreateContainer)}
|
||||
End Select
|
||||
End If
|
||||
End Using
|
||||
If Not c Is Nothing Then c.Load(f)
|
||||
End If
|
||||
Return c
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
390
SCrawler.YouTube/Base/YouTubeSettings.vb
Normal file
@@ -0,0 +1,390 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Globalization
|
||||
Imports System.Drawing.Design
|
||||
Imports System.ComponentModel
|
||||
Imports SCrawler.API.YouTube.Attributes
|
||||
Imports SCrawler.DownloadObjects.STDownloader
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports PersonalUtilities.Functions.XML.Objects
|
||||
Imports PersonalUtilities.Functions.XML.Attributes.Specialized
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Tools.Grid.Base
|
||||
Imports PersonalUtilities.Tools.Grid.Attributes
|
||||
Imports PersonalUtilities.Tools.Grid.Collections
|
||||
Imports PersonalUtilities.Tools.Grid.Specialized
|
||||
Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Namespace API.YouTube.Base
|
||||
<TypeDescriptionProvider(GetType(FieldsTypeDescriptorProvider))>
|
||||
Public Class YouTubeSettings : Implements IXMLValuesContainer, IGridValuesContainer, IDownloaderSettings
|
||||
#Region "Events"
|
||||
Private Event OnBeginUpdate As EventHandler Implements IXMLValuesContainer.OnBeginUpdate
|
||||
Private Event OnEndUpdate As EventHandler Implements IXMLValuesContainer.OnEndUpdate
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
<Browsable(False)> Private ReadOnly Property XML As XmlFile Implements IXMLValuesContainer.XML
|
||||
<Browsable(False)> Friend ReadOnly Property DesignXml As XmlFile
|
||||
<Browsable(False)> Private Property Mode As GridUpdateModes = GridUpdateModes.OnConfirm Implements IGridValuesContainer.Mode
|
||||
<Browsable(False), XMLVV(-1)> Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer)
|
||||
<Browsable(False)> Friend ReadOnly Property DownloadLocations As DownloadLocationsCollection
|
||||
#Region "Environment"
|
||||
#Region "Programs"
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment programs"), DisplayName("Path to yt-dlp.exe"),
|
||||
Description("Path to yt-dlp.exe file")>
|
||||
Public ReadOnly Property YTDLP As XMLValue(Of SFile)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment programs"), DisplayName("Path to ffmpeg.exe"),
|
||||
Description("Path to ffmpeg.exe file")>
|
||||
Public ReadOnly Property FFMPEG As XMLValue(Of SFile)
|
||||
<Browsable(False)> Private ReadOnly Property ENVIR_FFMPEG As SFile Implements IDownloaderSettings.ENVIR_FFMPEG
|
||||
Get
|
||||
Return FFMPEG
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(False)> Private ReadOnly Property ENVIR_YTDLP As SFile Implements IDownloaderSettings.ENVIR_YTDLP
|
||||
Get
|
||||
Return YTDLP
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(False)> Private ReadOnly Property ENVIR_GDL As SFile Implements IDownloaderSettings.ENVIR_GDL
|
||||
Get
|
||||
Return Nothing
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(False)> Private ReadOnly Property ENVIR_CURL As SFile Implements IDownloaderSettings.ENVIR_CURL
|
||||
Get
|
||||
Return Nothing
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
<Browsable(True), GridVisible(False), Category("Environment"), Description("YouTube cookies"), GridCollectionForm(GetType(CookieListForm2)),
|
||||
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
|
||||
Public ReadOnly Property Cookies As CookieKeeper
|
||||
Private Function ShouldSerializeCookies() As Boolean
|
||||
Return Cookies.Count > 0
|
||||
End Function
|
||||
Private Sub ResetCookies()
|
||||
Cookies.Clear()
|
||||
End Sub
|
||||
Private Class CookieListForm2 : Inherits CookieListForm
|
||||
Public Sub New()
|
||||
ShowGrid = False
|
||||
End Sub
|
||||
End Class
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, Provider:=GetType(XMLToFilePathProvider)), Category("Environment"), DisplayName("Output path"),
|
||||
Description("The default output path where files should be downloaded."),
|
||||
Editor(GetType(GridSFileTypeEditorPath), GetType(UITypeEditor))>
|
||||
Public ReadOnly Property OutputPath As XMLValue(Of SFile)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment"), DisplayName("Output path auto change"),
|
||||
Description("Automatically change the output path when a new destination is selected in the opening forms.")>
|
||||
Public ReadOnly Property OutputPathAutoChange As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Output path: ask for a name"),
|
||||
Description("Ask for a name when adding a new output path to the list.")>
|
||||
Public ReadOnly Property OutputPathAskForName As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property IDownloaderSettings_OutputPathAskForName As Boolean Implements IDownloaderSettings.OutputPathAskForName
|
||||
Get
|
||||
Return OutputPathAskForName
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Output path: auto add"),
|
||||
Description("Add new paths to the list automatically.")>
|
||||
Public ReadOnly Property OutputPathAutoAddPaths As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property IDownloaderSettings_OutputPathAutoAddPaths As Boolean Implements IDownloaderSettings.OutputPathAutoAddPaths
|
||||
Get
|
||||
Return OutputPathAutoAddPaths
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, DoubleClickBehavior.Folder), Category("Environment"), DisplayName("On item double click"),
|
||||
Description("What should program open when you double-click on an item...")>
|
||||
Public ReadOnly Property OnItemDoubleClick As XMLValue(Of DoubleClickBehavior)
|
||||
Private ReadOnly Property IDownloaderSettings_OnItemDoubleClick As DoubleClickBehavior Implements IDownloaderSettings.OnItemDoubleClick
|
||||
Get
|
||||
Return OnItemDoubleClick
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(False), GridVisible(False), XMLVN({"Environment"}), Category("Environment"), DisplayName("Open folders in another program"),
|
||||
Description("The command to open a folder.")>
|
||||
Public ReadOnly Property OpenFolderInOtherProgram As XMLValueUse(Of String)
|
||||
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program"), DefaultValue(False)>
|
||||
Private Property IDownloaderSettings_OpenFolderInOtherProgram As Boolean Implements IDownloaderSettings.OpenFolderInOtherProgram
|
||||
Get
|
||||
Return OpenFolderInOtherProgram.Use
|
||||
End Get
|
||||
Set(ByVal use As Boolean)
|
||||
OpenFolderInOtherProgram.Use = use
|
||||
End Set
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program (command)"),
|
||||
Description("The command to open a folder."), DefaultValue("")>
|
||||
Private Property IDownloaderSettings_OpenFolderInOtherProgram_Command As String Implements IDownloaderSettings.OpenFolderInOtherProgram_Command
|
||||
Get
|
||||
Return OpenFolderInOtherProgram
|
||||
End Get
|
||||
Set(ByVal command As String)
|
||||
OpenFolderInOtherProgram.Value = command
|
||||
End Set
|
||||
End Property
|
||||
#End Region
|
||||
#Region "Defaults"
|
||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Replace modification date"),
|
||||
Description("Set the file date to the date the video was added (website) (if available). Default: false.")>
|
||||
Public ReadOnly Property ReplaceModificationDate As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Use cookies"),
|
||||
Description("By default, use cookies when downloading from YouTube.")>
|
||||
Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"),
|
||||
DisplayName("Auto remove"), Description("Automatically remove downloaded items from the list.")>
|
||||
Public ReadOnly Property RemoveDownloadedAutomatically As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property IDownloaderSettings_RemoveDownloadedAutomatically As Boolean Implements IDownloaderSettings.RemoveDownloadedAutomatically
|
||||
Get
|
||||
Return RemoveDownloadedAutomatically
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Download Automatically"),
|
||||
Description("Download automatically when a new item is added.")>
|
||||
Public ReadOnly Property DownloadAutomatically As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property IDownloaderSettings_DownloadAutomatically As Boolean Implements IDownloaderSettings.DownloadAutomatically
|
||||
Get
|
||||
Return DownloadAutomatically
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, 1), Category("Defaults"), DisplayName("Max downloads"),
|
||||
Description("Maximum active downloads.")>
|
||||
Public ReadOnly Property MaxJobsCount As XMLValue(Of Integer)
|
||||
Private ReadOnly Property IDownloaderSettings_MaxJobsCount As Integer Implements IDownloaderSettings.MaxJobsCount
|
||||
Get
|
||||
Return MaxJobsCount
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Show notifications"),
|
||||
Description("Show a notification when the download is complete. The default value is true.")>
|
||||
Public ReadOnly Property ShowNotifications As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property IDownloaderSettings_ShowNotifications As Boolean Implements IDownloaderSettings.ShowNotifications
|
||||
Get
|
||||
Return ShowNotifications
|
||||
End Get
|
||||
End Property
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Show notifications every time"),
|
||||
Description("If true, notifications will be shown every time a file download is complete; " &
|
||||
"otherwise, the notification will only be shown when all downloads are completed. " &
|
||||
"Only works if 'Show notifications' is true." &
|
||||
"The default value is true.")>
|
||||
Public ReadOnly Property ShowNotificationsEveryDownload As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property IDownloaderSettings_ShowNotificationsEveryDownload As Boolean Implements IDownloaderSettings.ShowNotificationsEveryDownload
|
||||
Get
|
||||
Return ShowNotifications And ShowNotificationsEveryDownload
|
||||
End Get
|
||||
End Property
|
||||
Private Sub ShowNotificationsEveryDownload_TempValueChanged(ByVal Sender As Object, ByVal e As EventArgs)
|
||||
If ShowNotificationsEveryDownload.ValueTemp Then ShowNotifications.ValueTemp = True
|
||||
End Sub
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, False), Category("Defaults"), DisplayName("Close to tray"),
|
||||
Description("Close the program to tray.")>
|
||||
Public ReadOnly Property CloseToTray As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, False), Category("Defaults"), DisplayName("Confirm exit"),
|
||||
Description("Exit confirmation when closing the program.")>
|
||||
Public ReadOnly Property ExitConfirm As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Download on click in tray: show form"),
|
||||
Description("Show main window when download by clicking (Ctrl+Click) the tray icon. Default: false")>
|
||||
Public ReadOnly Property ShowFormDownTrayClick As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Program title"),
|
||||
Description("Change the title of the main window if you need to")>
|
||||
Friend ReadOnly Property ProgramText As XMLValue(Of String)
|
||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Program description"),
|
||||
Description("Add some additional info to the program info if you need")>
|
||||
Friend ReadOnly Property ProgramDescription As XMLValue(Of String)
|
||||
#End Region
|
||||
#Region "Defaults Video"
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, "MKV"), Category("Defaults Video"), DisplayName("Default format"),
|
||||
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableVideoFormats_Impl)),
|
||||
Description("The default video format for downloading videos.")>
|
||||
Public ReadOnly Property DefaultVideoFormat As XMLValue(Of String)
|
||||
Private Function AvailableVideoFormats_Impl() As String()
|
||||
Return AvailableVideoFormats
|
||||
End Function
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 1080), Category("Defaults Video"), DisplayName("Default definition"),
|
||||
Description("The default maximum video resolution. -1 for max definition")>
|
||||
Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}), Category("Defaults Video"), DisplayName("Include zero size formats"),
|
||||
Description("Include formats with zero size (or undefined size).")>
|
||||
Public ReadOnly Property DefaultVideoIncludeNullSize As XMLValue(Of Boolean)
|
||||
#End Region
|
||||
#Region "Defaults Audio"
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, "AAC"), Category("Defaults Audio"), DisplayName("Default codec"),
|
||||
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableAudioFormats_Impl)),
|
||||
Description("The default audio format for downloading videos.")>
|
||||
Public ReadOnly Property DefaultAudioCodec As XMLValue(Of String)
|
||||
Private Function AvailableAudioFormats_Impl() As String()
|
||||
Return AvailableAudioFormats
|
||||
End Function
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, "MP3"), Category("Defaults Audio"), DisplayName("Default codec for music"),
|
||||
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableAudioFormats_Impl)),
|
||||
Description("The default audio format for downloading music.")>
|
||||
Public ReadOnly Property DefaultAudioCodecMusic As XMLValue(Of String)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}), Category("Defaults Audio"), DisplayName("Additional codec"),
|
||||
Bindable(True), Editor(GetType(ValueCollectionEditor), GetType(UITypeEditor)),
|
||||
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
|
||||
TypeConverter(GetType(ValueCollectionConverter)),
|
||||
Description("Additional audio format for downloading videos. This means that the audio will be extracted and saved as a separate file in these formats.")>
|
||||
Public ReadOnly Property DefaultAudioCodecAddit As XMLValuesCollection(Of String)
|
||||
#End Region
|
||||
#Region "Defaults Subtitles"
|
||||
<XMLVN({"DefaultsSubtitles"}, {"en"}, CollectionMode:=IXMLValuesCollection.Modes.String)>
|
||||
Public ReadOnly Property DefaultSubtitles As XMLValuesCollection(Of String)
|
||||
<Browsable(True), GridVisible, Category("Defaults Subtitles"), DisplayName("Default subtitles"),
|
||||
Description("The default subtitles that should be downloaded with the video. The comma is the separator.")>
|
||||
Private Property DefaultSubtitles_Impl As String
|
||||
Get
|
||||
If DefaultSubtitles.ValueTemp.Count > 0 Then
|
||||
Return DefaultSubtitles.ValueTemp.ListToString(",")
|
||||
Else
|
||||
Return String.Empty
|
||||
End If
|
||||
End Get
|
||||
Set(ByVal s As String)
|
||||
If s.IsEmptyString Then
|
||||
DefaultSubtitles.ValueTemp = Nothing
|
||||
Else
|
||||
DefaultSubtitles.ValueTemp = ListAddList(Nothing, s.Split(","), LAP.NotContainsOnly,
|
||||
CType(Function(Input$) Input.StringTrim, Func(Of Object, Object)))
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
Private Function ShouldSerializeDefaultSubtitles_Impl() As Boolean
|
||||
Return DirectCast(DefaultSubtitles, IGridValue).ShouldSerializeValue
|
||||
End Function
|
||||
Private Sub ResetDefaultSubtitles_Impl()
|
||||
DirectCast(DefaultSubtitles, IGridValue).ResetValue()
|
||||
End Sub
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsSubtitles"}, "SRT"), Category("Defaults Subtitles"), DisplayName("Default format"),
|
||||
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableSubtitlesFormats_Impl)),
|
||||
Description("The default format for downloading subtitles.")>
|
||||
Public ReadOnly Property DefaultSubtitlesFormat As XMLValue(Of String)
|
||||
Private Function AvailableSubtitlesFormats_Impl() As String()
|
||||
Return AvailableSubtitlesFormats
|
||||
End Function
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsSubtitles"}, CollectionMode:=IXMLValuesCollection.Modes.String),
|
||||
Category("Defaults Subtitles"), DisplayName("Additional format"),
|
||||
Bindable(True), Editor(GetType(ValueCollectionEditor), GetType(UITypeEditor)),
|
||||
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
|
||||
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.")>
|
||||
Public ReadOnly Property DefaultSubtitlesFormatAddit As XMLValuesCollection(Of String)
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Public Sub New()
|
||||
DownloadLocations = New DownloadLocationsCollection
|
||||
DownloadLocations.Load(False, True)
|
||||
XML = New XmlFile(YouTubeSettingsFile,, False) With {.AutoUpdateFile = True}
|
||||
XML.LoadData(EDP.None)
|
||||
DesignXml = New XmlFile("Settings\DesignDownloader.xml", Protector.Modes.All, False)
|
||||
DesignXml.LoadData(EDP.None)
|
||||
InitializeXMLValueProperties(Me)
|
||||
AddHandler ShowNotificationsEveryDownload.TempValueChanged, AddressOf ShowNotificationsEveryDownload_TempValueChanged
|
||||
Cookies = New CookieKeeper
|
||||
Grid.Abstract.DesignerXmlSource.Add(New Grid.Abstract.DesignerXmlData(GetType(CookieListForm2), DesignXml, "CookiesListForm"))
|
||||
If YouTubeCookieNetscapeFile.Exists Then Cookies.AddRange(CookieKeeper.ParseNetscapeText(YouTubeCookieNetscapeFile.GetText(EDP.ReturnValue), EDP.None),, EDP.None)
|
||||
If Not YTDLP.Value.Exists Then YTDLP.Value = ProgramPath("yt-dlp.exe")
|
||||
If Not FFMPEG.Value.Exists Then FFMPEG.Value = ProgramPath("ffmpeg.exe")
|
||||
If Not OutputPath.Value.Exists(SFO.Path, False) Then OutputPath.Value = YouTubeDownloadPathDefault
|
||||
If XML.ChangesDetected Then XML.UpdateData()
|
||||
End Sub
|
||||
Private Function ProgramPath(ByVal Program As String) As SFile
|
||||
If Program.CSFile.Exists Then
|
||||
Return Program.CSFile
|
||||
ElseIf $"Environment\{Program}".CSFile.Exists Then
|
||||
Return $"Environment\{Program}"
|
||||
Else
|
||||
Return SystemEnvironment.FindFileInPaths(Program).ListIfNothing.FirstOrDefault
|
||||
End If
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Edit, Update"
|
||||
Protected Overridable Sub BeginUpdate() Implements IXMLValuesContainer.BeginUpdate, IGridValuesContainer.BeginUpdate
|
||||
XML.BeginUpdate()
|
||||
End Sub
|
||||
Protected Overridable Sub EndUpdate() Implements IXMLValuesContainer.EndUpdate, IGridValuesContainer.EndUpdate
|
||||
XML.EndUpdate()
|
||||
If XML.ChangesDetected Then XML.UpdateData()
|
||||
End Sub
|
||||
Protected Overridable Sub Apply() Implements IGridValuesContainer.Apply
|
||||
XMLValuesApply(Me)
|
||||
ApplyCookies()
|
||||
End Sub
|
||||
Protected Sub ApplyCookies()
|
||||
If Cookies.Count > 0 Then Cookies.SaveNetscapeFile(YouTubeCookieNetscapeFile) Else YouTubeCookieNetscapeFile.Delete(,, EDP.None)
|
||||
End Sub
|
||||
Private Sub BeginEdit() Implements IGridValuesContainer.BeginEdit
|
||||
XMLValuesBeginEdit(Me)
|
||||
End Sub
|
||||
Protected Overridable Sub EndEdit() Implements IGridValuesContainer.EndEdit
|
||||
XMLValuesEndEdit(Me)
|
||||
Cookies.Clear()
|
||||
If YouTubeCookieNetscapeFile.Exists Then Cookies.AddRange(CookieKeeper.ParseNetscapeText(YouTubeCookieNetscapeFile.GetText(EDP.ReturnValue), EDP.None),, EDP.None)
|
||||
End Sub
|
||||
Public Sub ShowForm(ByVal AppMode As Boolean)
|
||||
Using f As New SimpleGridForm(Me) With {
|
||||
.GridShowToolbar = False,
|
||||
.InitialOkValue = True,
|
||||
.ShowIcon = True,
|
||||
.Icon = My.Resources.SiteYouTube.YouTubeIcon_32,
|
||||
.Text = "YouTube Settings",
|
||||
.DesignXML = DesignXml,
|
||||
.DesignXMLNodeName = "YouTubeSettingsForm"
|
||||
}
|
||||
f.GridBrowsableAttributes = New AttributeCollection(New BrowsableAttribute(True), New GridVisibleAttribute(Not AppMode))
|
||||
f.ShowDialog()
|
||||
End Using
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Close"
|
||||
Friend Sub Close()
|
||||
DesignXml.Dispose()
|
||||
XML.Dispose()
|
||||
Cookies.Dispose()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Grid Support"
|
||||
Private Class ValueCollectionConverter : Inherits TypeConverter
|
||||
Public Overrides Function ConvertTo(ByVal Context As ITypeDescriptorContext, ByVal Culture As CultureInfo, ByVal Value As Object, ByVal DestinationType As Type) As Object
|
||||
If TypeOf Value Is IEnumerable Then
|
||||
Return DirectCast(Value, IEnumerable).ToObjectsList(Of String).ListToString
|
||||
Else
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
End Class
|
||||
Private Class ValueCollectionEditor : Inherits GridStructureCollectionEditor
|
||||
Public Overrides Function EditValue(ByVal Context As ITypeDescriptorContext, ByVal Provider As IServiceProvider, ByVal Value As Object) As Object
|
||||
Dim eObj As IEnumerable(Of String) = Nothing
|
||||
Select Case Context.PropertyDescriptor.Name
|
||||
Case NameOf(DefaultSubtitlesFormatAddit) : eObj = AvailableSubtitlesFormats
|
||||
Case NameOf(DefaultAudioCodecAddit) : eObj = AvailableAudioFormats
|
||||
End Select
|
||||
Using f As New SimpleListForm(Of String)(eObj) With {
|
||||
.Mode = SimpleListFormModes.CheckedItems,
|
||||
.DesignXML = MyYouTubeSettings.DesignXml,
|
||||
.DesignXMLNodeName = "YouTubeSettingsFormList",
|
||||
.FormText = DirectCast(Context.PropertyDescriptor.Attributes.Cast(Of Attribute).First(Function(a) a.GetType Is GetType(DisplayNameAttribute)), DisplayNameAttribute).DisplayName,
|
||||
.Icon = My.Resources.SiteYouTube.YouTubeIcon_32
|
||||
}
|
||||
f.DataSelected.ListAddList(Value)
|
||||
If f.ShowDialog() = DialogResult.OK Then
|
||||
eObj = f.DataResult.ToList
|
||||
With DirectCast(Value, List(Of String)) : .Clear() : .ListAddList(eObj) : End With
|
||||
End If
|
||||
End Using
|
||||
Return Value
|
||||
End Function
|
||||
End Class
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
BIN
SCrawler.YouTube/Content/Icons/YouTubeIcon_32.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
SCrawler.YouTube/Content/Icons/YouTubeMusicIcon_32.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
SCrawler.YouTube/Content/Pictures/ArrowDownPic_Blue_24.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
SCrawler.YouTube/Content/Pictures/AudioMusic_32.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCrawler.YouTube/Content/Pictures/ClockPic_16.png
Normal file
|
After Width: | Height: | Size: 457 B |
BIN
SCrawler.YouTube/Content/Pictures/HeartPic_32.png
Normal file
|
After Width: | Height: | Size: 525 B |
BIN
SCrawler.YouTube/Content/Pictures/ImagePic_32.png
Normal file
|
After Width: | Height: | Size: 569 B |
BIN
SCrawler.YouTube/Content/Pictures/InfoPic_32.png
Normal file
|
After Width: | Height: | Size: 368 B |
BIN
SCrawler.YouTube/Content/Pictures/LinkPic_32.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
SCrawler.YouTube/Content/Pictures/MailPic_16.png
Normal file
|
After Width: | Height: | Size: 209 B |
BIN
SCrawler.YouTube/Content/Pictures/RulerPic_32.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
SCrawler.YouTube/Content/Pictures/SettingsPic_16.bmp
Normal file
|
After Width: | Height: | Size: 824 B |
BIN
SCrawler.YouTube/Content/Pictures/StartPic_Green_16.png
Normal file
|
After Width: | Height: | Size: 373 B |
BIN
SCrawler.YouTube/Content/Pictures/VideoCamera_32.png
Normal file
|
After Width: | Height: | Size: 402 B |
BIN
SCrawler.YouTube/Content/Pictures/YouTubeMusicPic_96.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
SCrawler.YouTube/Content/Pictures/YouTubePic_96.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
496
SCrawler.YouTube/Controls/MusicPlaylistsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,496 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class MusicPlaylistsForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_PLS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_PLS_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_PLS_ITEMS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_SETTINGS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_FORMATS 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(MusicPlaylistsForm))
|
||||
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim LBL_FORMAT As System.Windows.Forms.Label
|
||||
Dim TP_LYRICS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
|
||||
Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.BTT_DOWN = New System.Windows.Forms.Button()
|
||||
Me.BTT_CANCEL = New System.Windows.Forms.Button()
|
||||
Me.SPLITTER_MAIN = New System.Windows.Forms.SplitContainer()
|
||||
Me.LIST_PLAYLISTS = New System.Windows.Forms.CheckedListBox()
|
||||
Me.BTT_PLS_ALL = New System.Windows.Forms.Button()
|
||||
Me.BTT_PLS_NONE = New System.Windows.Forms.Button()
|
||||
Me.LIST_ITEMS = New System.Windows.Forms.CheckedListBox()
|
||||
Me.TXT_FORMATS_ADDIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CMB_FORMATS = New System.Windows.Forms.ComboBox()
|
||||
Me.TXT_SUBS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CH_DOWN_LYRICS = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_OUTPUT_PATH = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_PLS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_PLS_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_PLS_ITEMS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_SETTINGS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_FORMATS = New System.Windows.Forms.TableLayoutPanel()
|
||||
LBL_FORMAT = New System.Windows.Forms.Label()
|
||||
TP_LYRICS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
TP_MAIN.SuspendLayout()
|
||||
TP_BUTTONS.SuspendLayout()
|
||||
CType(Me.SPLITTER_MAIN, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.SPLITTER_MAIN.Panel1.SuspendLayout()
|
||||
Me.SPLITTER_MAIN.Panel2.SuspendLayout()
|
||||
Me.SPLITTER_MAIN.SuspendLayout()
|
||||
TP_PLS.SuspendLayout()
|
||||
TP_PLS_BUTTONS.SuspendLayout()
|
||||
TP_PLS_ITEMS.SuspendLayout()
|
||||
TP_SETTINGS.SuspendLayout()
|
||||
TP_FORMATS.SuspendLayout()
|
||||
CType(Me.TXT_FORMATS_ADDIT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TP_LYRICS.SuspendLayout()
|
||||
CType(Me.TXT_SUBS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_OUTPUT_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'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_BUTTONS, 0, 2)
|
||||
TP_MAIN.Controls.Add(Me.SPLITTER_MAIN, 0, 1)
|
||||
TP_MAIN.Controls.Add(TP_SETTINGS, 0, 0)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 3
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 84.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, 25.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(434, 261)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_BUTTONS
|
||||
'
|
||||
TP_BUTTONS.ColumnCount = 3
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100.0!))
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100.0!))
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_DOWN, 1, 0)
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_CANCEL, 2, 0)
|
||||
TP_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_BUTTONS.Location = New System.Drawing.Point(0, 236)
|
||||
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, 25.0!))
|
||||
TP_BUTTONS.Size = New System.Drawing.Size(434, 25)
|
||||
TP_BUTTONS.TabIndex = 2
|
||||
'
|
||||
'BTT_DOWN
|
||||
'
|
||||
Me.BTT_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_DOWN.Location = New System.Drawing.Point(236, 2)
|
||||
Me.BTT_DOWN.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_DOWN.Name = "BTT_DOWN"
|
||||
Me.BTT_DOWN.Size = New System.Drawing.Size(96, 21)
|
||||
Me.BTT_DOWN.TabIndex = 0
|
||||
Me.BTT_DOWN.Text = "Download"
|
||||
Me.BTT_DOWN.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_CANCEL
|
||||
'
|
||||
Me.BTT_CANCEL.DialogResult = System.Windows.Forms.DialogResult.Cancel
|
||||
Me.BTT_CANCEL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_CANCEL.Location = New System.Drawing.Point(336, 2)
|
||||
Me.BTT_CANCEL.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_CANCEL.Name = "BTT_CANCEL"
|
||||
Me.BTT_CANCEL.Size = New System.Drawing.Size(96, 21)
|
||||
Me.BTT_CANCEL.TabIndex = 1
|
||||
Me.BTT_CANCEL.Text = "Cancel"
|
||||
Me.BTT_CANCEL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'SPLITTER_MAIN
|
||||
'
|
||||
Me.SPLITTER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.SPLITTER_MAIN.Location = New System.Drawing.Point(3, 87)
|
||||
Me.SPLITTER_MAIN.Name = "SPLITTER_MAIN"
|
||||
'
|
||||
'SPLITTER_MAIN.Panel1
|
||||
'
|
||||
Me.SPLITTER_MAIN.Panel1.Controls.Add(TP_PLS)
|
||||
Me.SPLITTER_MAIN.Panel1MinSize = 110
|
||||
'
|
||||
'SPLITTER_MAIN.Panel2
|
||||
'
|
||||
Me.SPLITTER_MAIN.Panel2.Controls.Add(TP_PLS_ITEMS)
|
||||
Me.SPLITTER_MAIN.Size = New System.Drawing.Size(428, 146)
|
||||
Me.SPLITTER_MAIN.SplitterDistance = 142
|
||||
Me.SPLITTER_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_PLS
|
||||
'
|
||||
TP_PLS.ColumnCount = 1
|
||||
TP_PLS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_PLS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_PLS.Controls.Add(Me.LIST_PLAYLISTS, 0, 0)
|
||||
TP_PLS.Controls.Add(TP_PLS_BUTTONS, 0, 1)
|
||||
TP_PLS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_PLS.Location = New System.Drawing.Point(0, 0)
|
||||
TP_PLS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_PLS.Name = "TP_PLS"
|
||||
TP_PLS.RowCount = 2
|
||||
TP_PLS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_PLS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_PLS.Size = New System.Drawing.Size(142, 146)
|
||||
TP_PLS.TabIndex = 0
|
||||
'
|
||||
'LIST_PLAYLISTS
|
||||
'
|
||||
Me.LIST_PLAYLISTS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LIST_PLAYLISTS.FormattingEnabled = True
|
||||
Me.LIST_PLAYLISTS.Location = New System.Drawing.Point(3, 3)
|
||||
Me.LIST_PLAYLISTS.Name = "LIST_PLAYLISTS"
|
||||
Me.LIST_PLAYLISTS.Size = New System.Drawing.Size(136, 115)
|
||||
Me.LIST_PLAYLISTS.TabIndex = 0
|
||||
Me.LIST_PLAYLISTS.ThreeDCheckBoxes = True
|
||||
'
|
||||
'TP_PLS_BUTTONS
|
||||
'
|
||||
TP_PLS_BUTTONS.ColumnCount = 3
|
||||
TP_PLS_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50.0!))
|
||||
TP_PLS_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50.0!))
|
||||
TP_PLS_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_PLS_BUTTONS.Controls.Add(Me.BTT_PLS_ALL, 0, 0)
|
||||
TP_PLS_BUTTONS.Controls.Add(Me.BTT_PLS_NONE, 1, 0)
|
||||
TP_PLS_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_PLS_BUTTONS.Location = New System.Drawing.Point(0, 121)
|
||||
TP_PLS_BUTTONS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_PLS_BUTTONS.Name = "TP_PLS_BUTTONS"
|
||||
TP_PLS_BUTTONS.RowCount = 1
|
||||
TP_PLS_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_PLS_BUTTONS.Size = New System.Drawing.Size(142, 25)
|
||||
TP_PLS_BUTTONS.TabIndex = 1
|
||||
'
|
||||
'BTT_PLS_ALL
|
||||
'
|
||||
Me.BTT_PLS_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_PLS_ALL.Location = New System.Drawing.Point(2, 2)
|
||||
Me.BTT_PLS_ALL.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_PLS_ALL.Name = "BTT_PLS_ALL"
|
||||
Me.BTT_PLS_ALL.Size = New System.Drawing.Size(46, 21)
|
||||
Me.BTT_PLS_ALL.TabIndex = 0
|
||||
Me.BTT_PLS_ALL.Tag = "a"
|
||||
Me.BTT_PLS_ALL.Text = "All"
|
||||
TT_MAIN.SetToolTip(Me.BTT_PLS_ALL, "Select all")
|
||||
Me.BTT_PLS_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_PLS_NONE
|
||||
'
|
||||
Me.BTT_PLS_NONE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_PLS_NONE.Location = New System.Drawing.Point(52, 2)
|
||||
Me.BTT_PLS_NONE.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_PLS_NONE.Name = "BTT_PLS_NONE"
|
||||
Me.BTT_PLS_NONE.Size = New System.Drawing.Size(46, 21)
|
||||
Me.BTT_PLS_NONE.TabIndex = 1
|
||||
Me.BTT_PLS_NONE.Tag = "n"
|
||||
Me.BTT_PLS_NONE.Text = "None"
|
||||
TT_MAIN.SetToolTip(Me.BTT_PLS_NONE, "Select none")
|
||||
Me.BTT_PLS_NONE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_PLS_ITEMS
|
||||
'
|
||||
TP_PLS_ITEMS.ColumnCount = 1
|
||||
TP_PLS_ITEMS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_PLS_ITEMS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_PLS_ITEMS.Controls.Add(Me.LIST_ITEMS, 0, 0)
|
||||
TP_PLS_ITEMS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_PLS_ITEMS.Location = New System.Drawing.Point(0, 0)
|
||||
TP_PLS_ITEMS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_PLS_ITEMS.Name = "TP_PLS_ITEMS"
|
||||
TP_PLS_ITEMS.RowCount = 2
|
||||
TP_PLS_ITEMS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_PLS_ITEMS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_PLS_ITEMS.Size = New System.Drawing.Size(282, 146)
|
||||
TP_PLS_ITEMS.TabIndex = 1
|
||||
'
|
||||
'LIST_ITEMS
|
||||
'
|
||||
Me.LIST_ITEMS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LIST_ITEMS.FormattingEnabled = True
|
||||
Me.LIST_ITEMS.Location = New System.Drawing.Point(3, 3)
|
||||
Me.LIST_ITEMS.Name = "LIST_ITEMS"
|
||||
Me.LIST_ITEMS.Size = New System.Drawing.Size(276, 115)
|
||||
Me.LIST_ITEMS.TabIndex = 0
|
||||
'
|
||||
'TP_SETTINGS
|
||||
'
|
||||
TP_SETTINGS.ColumnCount = 1
|
||||
TP_SETTINGS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_SETTINGS.Controls.Add(TP_FORMATS, 0, 1)
|
||||
TP_SETTINGS.Controls.Add(TP_LYRICS, 0, 0)
|
||||
TP_SETTINGS.Controls.Add(Me.TXT_OUTPUT_PATH, 0, 2)
|
||||
TP_SETTINGS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_SETTINGS.Location = New System.Drawing.Point(0, 0)
|
||||
TP_SETTINGS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_SETTINGS.Name = "TP_SETTINGS"
|
||||
TP_SETTINGS.RowCount = 3
|
||||
TP_SETTINGS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_SETTINGS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_SETTINGS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_SETTINGS.Size = New System.Drawing.Size(434, 84)
|
||||
TP_SETTINGS.TabIndex = 1
|
||||
'
|
||||
'TP_FORMATS
|
||||
'
|
||||
TP_FORMATS.ColumnCount = 3
|
||||
TP_FORMATS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50.0!))
|
||||
TP_FORMATS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 65.0!))
|
||||
TP_FORMATS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_FORMATS.Controls.Add(Me.TXT_FORMATS_ADDIT, 2, 0)
|
||||
TP_FORMATS.Controls.Add(LBL_FORMAT, 0, 0)
|
||||
TP_FORMATS.Controls.Add(Me.CMB_FORMATS, 1, 0)
|
||||
TP_FORMATS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_FORMATS.Location = New System.Drawing.Point(0, 28)
|
||||
TP_FORMATS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_FORMATS.Name = "TP_FORMATS"
|
||||
TP_FORMATS.RowCount = 1
|
||||
TP_FORMATS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_FORMATS.Size = New System.Drawing.Size(434, 28)
|
||||
TP_FORMATS.TabIndex = 1
|
||||
'
|
||||
'TXT_FORMATS_ADDIT
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Enabled = False
|
||||
ActionButton1.Name = "Open"
|
||||
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton2.Enabled = False
|
||||
ActionButton2.Name = "Refresh"
|
||||
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Enabled = False
|
||||
ActionButton3.Name = "Clear"
|
||||
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_FORMATS_ADDIT.Buttons.Add(ActionButton1)
|
||||
Me.TXT_FORMATS_ADDIT.Buttons.Add(ActionButton2)
|
||||
Me.TXT_FORMATS_ADDIT.Buttons.Add(ActionButton3)
|
||||
Me.TXT_FORMATS_ADDIT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
|
||||
Me.TXT_FORMATS_ADDIT.CaptionText = "Additional formats"
|
||||
Me.TXT_FORMATS_ADDIT.CaptionToolTipEnabled = True
|
||||
Me.TXT_FORMATS_ADDIT.CaptionToolTipText = "Convert every downloaded track to the formats you choose."
|
||||
Me.TXT_FORMATS_ADDIT.CaptionWidth = 115.0R
|
||||
Me.TXT_FORMATS_ADDIT.ClearTextByButtonClear = False
|
||||
Me.TXT_FORMATS_ADDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_FORMATS_ADDIT.Location = New System.Drawing.Point(118, 3)
|
||||
Me.TXT_FORMATS_ADDIT.Name = "TXT_FORMATS_ADDIT"
|
||||
Me.TXT_FORMATS_ADDIT.Size = New System.Drawing.Size(313, 22)
|
||||
Me.TXT_FORMATS_ADDIT.TabIndex = 2
|
||||
Me.TXT_FORMATS_ADDIT.Tag = "a"
|
||||
Me.TXT_FORMATS_ADDIT.TextBoxReadOnly = True
|
||||
'
|
||||
'LBL_FORMAT
|
||||
'
|
||||
LBL_FORMAT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
LBL_FORMAT.Location = New System.Drawing.Point(3, 0)
|
||||
LBL_FORMAT.Margin = New System.Windows.Forms.Padding(3, 0, 0, 0)
|
||||
LBL_FORMAT.Name = "LBL_FORMAT"
|
||||
LBL_FORMAT.Size = New System.Drawing.Size(47, 28)
|
||||
LBL_FORMAT.TabIndex = 0
|
||||
LBL_FORMAT.Text = "Format:"
|
||||
LBL_FORMAT.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
TT_MAIN.SetToolTip(LBL_FORMAT, "Output files format")
|
||||
'
|
||||
'CMB_FORMATS
|
||||
'
|
||||
Me.CMB_FORMATS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CMB_FORMATS.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
|
||||
Me.CMB_FORMATS.FormattingEnabled = True
|
||||
Me.CMB_FORMATS.Location = New System.Drawing.Point(53, 3)
|
||||
Me.CMB_FORMATS.Name = "CMB_FORMATS"
|
||||
Me.CMB_FORMATS.Size = New System.Drawing.Size(59, 21)
|
||||
Me.CMB_FORMATS.TabIndex = 1
|
||||
'
|
||||
'TP_LYRICS
|
||||
'
|
||||
TP_LYRICS.ColumnCount = 2
|
||||
TP_LYRICS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 115.0!))
|
||||
TP_LYRICS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_LYRICS.Controls.Add(Me.TXT_SUBS, 1, 0)
|
||||
TP_LYRICS.Controls.Add(Me.CH_DOWN_LYRICS, 0, 0)
|
||||
TP_LYRICS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_LYRICS.Location = New System.Drawing.Point(0, 0)
|
||||
TP_LYRICS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_LYRICS.Name = "TP_LYRICS"
|
||||
TP_LYRICS.RowCount = 1
|
||||
TP_LYRICS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_LYRICS.Size = New System.Drawing.Size(434, 28)
|
||||
TP_LYRICS.TabIndex = 0
|
||||
'
|
||||
'TXT_SUBS
|
||||
'
|
||||
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton4.Enabled = False
|
||||
ActionButton4.Name = "Open"
|
||||
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton5.Enabled = False
|
||||
ActionButton5.Name = "Refresh"
|
||||
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
|
||||
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton6.Enabled = False
|
||||
ActionButton6.Name = "Clear"
|
||||
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_SUBS.Buttons.Add(ActionButton4)
|
||||
Me.TXT_SUBS.Buttons.Add(ActionButton5)
|
||||
Me.TXT_SUBS.Buttons.Add(ActionButton6)
|
||||
Me.TXT_SUBS.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
|
||||
Me.TXT_SUBS.CaptionText = "Additional lyrics"
|
||||
Me.TXT_SUBS.CaptionToolTipEnabled = True
|
||||
Me.TXT_SUBS.CaptionToolTipText = "Convert all downloaded lyrics to the formats you choose."
|
||||
Me.TXT_SUBS.CaptionWidth = 115.0R
|
||||
Me.TXT_SUBS.ClearTextByButtonClear = False
|
||||
Me.TXT_SUBS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_SUBS.Location = New System.Drawing.Point(118, 3)
|
||||
Me.TXT_SUBS.Name = "TXT_SUBS"
|
||||
Me.TXT_SUBS.Size = New System.Drawing.Size(313, 22)
|
||||
Me.TXT_SUBS.TabIndex = 1
|
||||
Me.TXT_SUBS.Tag = "s"
|
||||
Me.TXT_SUBS.TextBoxReadOnly = True
|
||||
'
|
||||
'CH_DOWN_LYRICS
|
||||
'
|
||||
Me.CH_DOWN_LYRICS.AutoSize = True
|
||||
Me.CH_DOWN_LYRICS.CheckAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
Me.CH_DOWN_LYRICS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_LYRICS.Location = New System.Drawing.Point(3, 3)
|
||||
Me.CH_DOWN_LYRICS.Name = "CH_DOWN_LYRICS"
|
||||
Me.CH_DOWN_LYRICS.Size = New System.Drawing.Size(109, 22)
|
||||
Me.CH_DOWN_LYRICS.TabIndex = 0
|
||||
Me.CH_DOWN_LYRICS.Text = "Download lyrics"
|
||||
Me.CH_DOWN_LYRICS.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
TT_MAIN.SetToolTip(Me.CH_DOWN_LYRICS, "Download lyrics if available")
|
||||
Me.CH_DOWN_LYRICS.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TXT_OUTPUT_PATH
|
||||
'
|
||||
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton7.Name = "Open"
|
||||
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||
ActionButton7.ToolTipText = "Choose a new location (Ctrl+O)"
|
||||
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton8.Name = "Add"
|
||||
ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Add
|
||||
ActionButton8.ToolTipText = "Choose a new location and add it to the list (Alt+O)"
|
||||
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton9.Name = "Clear"
|
||||
ActionButton9.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton10.Name = "ArrowDown"
|
||||
ActionButton10.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
|
||||
Me.TXT_OUTPUT_PATH.Buttons.Add(ActionButton7)
|
||||
Me.TXT_OUTPUT_PATH.Buttons.Add(ActionButton8)
|
||||
Me.TXT_OUTPUT_PATH.Buttons.Add(ActionButton9)
|
||||
Me.TXT_OUTPUT_PATH.Buttons.Add(ActionButton10)
|
||||
Me.TXT_OUTPUT_PATH.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
|
||||
Me.TXT_OUTPUT_PATH.CaptionText = "Output path"
|
||||
Me.TXT_OUTPUT_PATH.CaptionVisible = True
|
||||
Me.TXT_OUTPUT_PATH.CaptionWidth = 112.0R
|
||||
ListColumn1.Name = "COL_NAME"
|
||||
ListColumn1.Text = "Name"
|
||||
ListColumn1.Width = -1
|
||||
ListColumn2.DisplayMember = True
|
||||
ListColumn2.Name = "COL_VALUE"
|
||||
ListColumn2.Text = "Value"
|
||||
ListColumn2.ValueMember = True
|
||||
ListColumn2.Visible = False
|
||||
Me.TXT_OUTPUT_PATH.Columns.Add(ListColumn1)
|
||||
Me.TXT_OUTPUT_PATH.Columns.Add(ListColumn2)
|
||||
Me.TXT_OUTPUT_PATH.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_OUTPUT_PATH.Location = New System.Drawing.Point(3, 59)
|
||||
Me.TXT_OUTPUT_PATH.Name = "TXT_OUTPUT_PATH"
|
||||
Me.TXT_OUTPUT_PATH.Size = New System.Drawing.Size(428, 22)
|
||||
Me.TXT_OUTPUT_PATH.TabIndex = 2
|
||||
Me.TXT_OUTPUT_PATH.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
|
||||
'
|
||||
'MusicPlaylistsForm
|
||||
'
|
||||
Me.AcceptButton = Me.BTT_DOWN
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.CancelButton = Me.BTT_CANCEL
|
||||
Me.ClientSize = New System.Drawing.Size(434, 261)
|
||||
Me.Controls.Add(TP_MAIN)
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeMusicIcon_32
|
||||
Me.KeyPreview = True
|
||||
Me.MinimumSize = New System.Drawing.Size(450, 300)
|
||||
Me.Name = "MusicPlaylistsForm"
|
||||
Me.Text = "Albums"
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_BUTTONS.ResumeLayout(False)
|
||||
Me.SPLITTER_MAIN.Panel1.ResumeLayout(False)
|
||||
Me.SPLITTER_MAIN.Panel2.ResumeLayout(False)
|
||||
CType(Me.SPLITTER_MAIN, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.SPLITTER_MAIN.ResumeLayout(False)
|
||||
TP_PLS.ResumeLayout(False)
|
||||
TP_PLS_BUTTONS.ResumeLayout(False)
|
||||
TP_PLS_ITEMS.ResumeLayout(False)
|
||||
TP_SETTINGS.ResumeLayout(False)
|
||||
TP_FORMATS.ResumeLayout(False)
|
||||
CType(Me.TXT_FORMATS_ADDIT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TP_LYRICS.ResumeLayout(False)
|
||||
TP_LYRICS.PerformLayout()
|
||||
CType(Me.TXT_SUBS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_OUTPUT_PATH, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents BTT_DOWN As Button
|
||||
Private WithEvents BTT_CANCEL As Button
|
||||
Private WithEvents LIST_PLAYLISTS As CheckedListBox
|
||||
Private WithEvents LIST_ITEMS As CheckedListBox
|
||||
Private WithEvents TXT_SUBS As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents BTT_PLS_ALL As Button
|
||||
Private WithEvents BTT_PLS_NONE As Button
|
||||
Private WithEvents TXT_FORMATS_ADDIT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents CMB_FORMATS As ComboBox
|
||||
Private WithEvents SPLITTER_MAIN As SplitContainer
|
||||
Private WithEvents CH_DOWN_LYRICS As CheckBox
|
||||
Private WithEvents TXT_OUTPUT_PATH As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||
End Class
|
||||
End Namespace
|
||||
355
SCrawler.YouTube/Controls/MusicPlaylistsForm.resx
Normal file
@@ -0,0 +1,355 @@
|
||||
<?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="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>
|
||||
<metadata name="TP_PLS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_PLS_BUTTONS.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>
|
||||
<metadata name="TP_PLS_ITEMS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_SETTINGS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_FORMATS.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
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton2.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="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="LBL_FORMAT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_LYRICS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton5.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="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlE
|
||||
QVRIS62WWWxMURjHL220JW1HausmlFrDFKUhnUGH6bRFzJ2idImlC0Vp2mlji1A8iNhCPIjIRES8EU+W
|
||||
h2oEtbSDTk3HNNM7S01VKsXjkb/vXBo3k1Ee7sMvmZzzzf//ne/+z50RAAxL1MUIG4G/YAv3HSVhF5Vw
|
||||
IYNdz3LadVj9RgdTB+HQYYPHIJuE1ocSdlEJFzG+1bPRLQLinglIeCkg+XUkKvz56hnkOfQs/rmA8S9H
|
||||
YEp7FDI64tAQtKhnsMapZ7zzNHsUFnbGY4VzIk70l6hnIH4wsDR7NBZ3apDrSqL5T8eFgUr1DLZ78lim
|
||||
Q4N8VzK29MxEpZSBa4M16hnU+c3M9CEFpdJsVHsXos63DDcHrf9nQEXD5VymwW/5USLNwl5vJhp7dTgW
|
||||
NML2pR7jbsUMS+KdMTa5Q8NQxinfBU4dRFcOyjy52OtbhwOBDTgZLKPPmTgY0ON4MBdNfSbYBupxY8Aq
|
||||
G10dqMG5/nIc7ytGQ6CQRliAamkTN/g1Ai4e95Qy3iogpX0UtBRDnhRzdxq2SXOxz5eFQ70rScCEU335
|
||||
ssGxj0YS06HSm4GN3ekwdE2C1hGH1LZR0JDOJof5jwHvnIvzTa0jlooTYfktvt+fhcOBHDQFTWRgxJGP
|
||||
ObAGsulZLMLWnjlY756K5c4JmNcRi6T2SGheCIihS2l5ozAo6NRhMolnUAcGV6IcwwqvFrX+JTjYuwKH
|
||||
SfRAYDms/mzs9y1GFe2VSnOw1j0FejqpLN4WCX4ZufiIBwLMLxQGm12rsLQzgWKYgmLPLNTQw6ynpDSS
|
||||
IBet8y+TqaVRVdFIeJrWuCcj+/0EzH43BomvIhBLI45uFiDcJ+6QwROFwa6+Amb9bGFNg6Xs9Ncd7Oy3
|
||||
Knb2eyU7/20nu9y/m136tIvEl6BC0qKoZwby3alo9JVhj7T5R7m/kJVIIityi8zyXmTiW+I10SqyIQNb
|
||||
uIgNwYuuf25kFd75KPKkI49OmUWnrfYWyXv/wBb2cijhhVf6a9lGei65XclYRDd6mj0GWz2iLBJaH0rY
|
||||
RSVc5Eywmhm7kuQXHX+bJlBStrh+zTi0PpSwi0q4yNFAOVvgiEcKJWUsxZn/NhT+znlofShhF5VwkRpv
|
||||
MUtti4KGYjj6sYCIh5QSu4oG27stjItHU+cjeQzvkcFzFQ2KnSKLoc4FukDCXeI2GbSoaFD4ziyPxNxK
|
||||
0AUyNxOP1DOwcaG/8I+/LRB+At7psBnyDBG0AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton10.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
|
||||
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
|
||||
GlAKCkhEC4KgQlsLQkqhKi/lrYWWlxaw3dLddrerz/Q89+7dc2fbfTn3npf5fJJv2rS758z85nnOzJz5
|
||||
nZktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMK3O3r79wVUIz65jfGNVxI/VIX69CvGO9M//a9P+e8o3B/8v
|
||||
vKn9s+3fyX8dAJgmaWd+fl3E96Wd/E9XdvZHkfbvXNa+Rn45AGCS3bvjj/E/h3box5OrmxjPyy8PAEyS
|
||||
XXO7zqhCeH/HDnwUOdCE+J6zdux4eH47YIrEGE8uy/Ls9Bnx/LooL0oH9b9Th/I1TVG+rCqKC+q6Xsh/
|
||||
FJgmO8vy6WknfdPQTnsjckMdwlPy2wITLO3wF6si/lGas1ekuXvX0Fzuyg9S3psOCl6qDwimQB3ji9Ok
|
||||
3btmEm907kpnEa/Mbw9Mlq1pB/6cdHZ/ZcfcPZrcXoXyrVVVFfl1gUmSdsS/libqPUMTd5NSvjktwrbB
|
||||
kgDjVi1UT26K+Nnu+XrMuaud60uPWHpIfhtg3JqyfEaanHcPTdZNTRPCPy4uLj40LxIwBudt2fKAtOP/
|
||||
0zQnN+5koIg3tpca81sC49J+LZcm5a3rJulYEq6LSV40YBOFEB6V5uFV6+flRiTsSwf9r81vDYzBCSO4
|
||||
vjfq/KAuiqfm5QM2QRPjuWnubUbz71DCn6W33zpYCmDT1EX5m92Tcuy5q47xFXkxgQ3UduqnOXfn0Bzc
|
||||
xJSvz4sCbIb2pzlp8v1w/WScnKSzkjekRT1hsMTAKC0vL5/Ydud3zb1NT1FelBcL2GiDm3d0TMTJy0ea
|
||||
pjk1LzYwAu3NvtLc+uTQXBtn7tYYCJtja/vQno5JOJFpQrzWb4hhNJoQnpjm1Q3D82wCcnNRFKfnxQQ2
|
||||
Qttk1zH5JjzhFmcIcHzyzb6O5aFem5J0sP/OvKjARmg7b7sm3xRkT3vDorwawJHb1t6Ep2NOTVoOtDch
|
||||
yssMjFr6IPh8x8SbnsT4lrQamgPhCMzPzz+sifHjnXNpMnN5XnRglJaWlk5KE2z/0ISbxnzQQ0bgvlXz
|
||||
1ePSXPnG0NyZ+DRF8Zi8CsCo7Azh0V0TbkrzRc2B0G3wIJ9429CcmZLce4MgYJTyff87JtzU5uayLM/J
|
||||
qwcM7vD5+jQ3DgzNlWnKDXldgFFJZwW/2jHZpj1727uZ5VWE3mofqJXmw4eG5sdUpqqqXXm1gFGoQnhJ
|
||||
12SbgRxoYvzjtIruK04vxRjPSvPgK0PzYmqTPqtemVcNGIU6xgu7JtusJH1ovH9ubu6UvLrQC2ncPyuN
|
||||
/58Mz4fpTvnmvHrAKJQL5dO6J9ssJXxucWFhLq8yzLKtaUf5h2ncb9zz+8eUKsYP53UERmHX/PyOrsk2
|
||||
g7nJDUWYZUuPWHpIE8oPdIz92UiMn86rCoxIOmOYta8KD5uftk2Peb1hZtTzdVOHcF3HmJ+ZVCF+Ia8u
|
||||
MCppcl0+PNlmOG1zYPtYYc2BzIQ0np+ZxvWPh8b5LObqvMrAqEzRo4BHmctijCfnEsBUqkP5u2ksz8Kd
|
||||
PI8g5SfyagOj0jbIpQk2c01DR5Brmh3NfC4DTI324LWO8V0dY3pm48mAsEGm7OEgo0sRb9wZ4+NzGWDi
|
||||
lWUZ0ti9Zt1YnvUU8fdyCYBRmsFbAh9xqhDvqEN4Xi4FTKz8s93vD4/hPiSdpJyXywCMWPtrgKuGJ12P
|
||||
ck/6gPmDXAuYOHVR/lY6UN3XMXb7kDv17MAGqhaqJ6WJ1sdegDUJ726a5oG5JDB2917vL+Kl3eO1N/lQ
|
||||
LgewUdIO8E0dk69vubosy+25JDA2bYNuFeJnOsZovxLjhbkkwEZZXl4+0QfOvfl2Ogg4O5cFNl1dFE9N
|
||||
4/B7Q+Oyj7mh/VzKZQE2UtM0j6iL+LWOidizhN3OPBiHuigvSmPwrvVjsn9pQnh1LguwGQa3Fo3fHp6M
|
||||
Pcw97c1WcllgQy0tLZ2UDr7/qmMc9jJNiF/WkwNjMHhQ0GzfX/yIU8RLfRCxkdq+kzTfrugcf/3MgZ1l
|
||||
+fRcHmCztU8Yq2P8h47J2cdcpTmQjdCE8IQ0vnzjdkjKP8nlAcZoWxXin3dP0n4l1eGb9UL92FwXOG51
|
||||
Ub48ja09w2Otz2nvTJpKs21QIWDs0lnKb6TJqTEphN3NQvncXBY4VtvSju4N3WOs17l6cXHxoblGwKRo
|
||||
r8mlHeAtHZO2b9mfDohem8sCR2XX3K4z0hj65NCYklSTGONpuUzApNlVFFWaqP81NHF7mvD2tnM7lwbu
|
||||
V/vwqTR2vrV+LPU7VSjf4ff+MAU0B65NeWVd12fm0sBhpTnzosHDp7rGUV8T9lVFvDiXCJgSrmEezDea
|
||||
onhMrgsM25rmyuvSODkwNG56nvZyYvi5XCNg2mgOXM3tVVH9ci4L3KtpmlN9W7Y+VYhfiEkuEzCt8n3L
|
||||
fzA8yXuY/b7OZEVZlovt3ew6xknf8965ublTcpmAaac5cG3C2zQ09Vv7bVAaC/+7fmz0Og6QYVZpDlyT
|
||||
GD/dPlgpl4b+2Nru5NIYuGfdmOhxmhB/VBblL+QaATNKc+DBfH1nCI/OdWHGtTewSdv874fGgIT4xfYb
|
||||
wlwmYNZpDlzNbVUIz85lYUblJ2i6BDacGP/u7O3bH5zLBPSF5sDV7K+L+Nu5LMyYtJP7xbSNfzy0zfue
|
||||
A+03gak8WwdVAnpHc+CaxHiJ5sCZsnK9f/+6bd3v3JZ2/r+SawT0mebAg0kfjB93v/Pp136t3X693bWN
|
||||
e56v6nsBhmkOXE24Ph0EnJXrwpSp63qhDuXnu7dtn1P+U1VVP5PLBHAozYGDtD+LchvU6TN4Iqa+lqGs
|
||||
XO8/YVAlgMPQHLiSsC+dNb0ml4UJVxflRWm73b1+O/Y5YXcVwvNziQDun+bANYnxkvO2bHlALg0TJsZ4
|
||||
cl3ESzu3Xa8Trm+KYimXCeDIaQ48mKqIH9McOHl2zc/vaIr42a5t1vN8tCiK03OZAI6J5sCVFPFr7QNk
|
||||
cl0Ys3yp6nvrtlO/s3K9f9ugSgDHSXPgILk58PxcFsYkX+93J8s1qUK8oynKF+YSAYyO5sCVhH3pgOjV
|
||||
uSxsoqZpHpjq//bu7dLjFPHGND+Xc5kARk9z4JrE+JZUEl+1bpLFhYW5VPf/WLcd5N/ruj4zlwlg42gO
|
||||
PCQfdXOVjdeE8MRU6xuGai9uXw2MgebA1YTrFkMoc10YsaYoX5rqfOf6uvc6e9LO/xW5RACbT3Pgam5N
|
||||
B0Q/m8vCCLT3XnCQ2ZXwnWqhenIuE8D4aA5czV3OykZj19yuM1I9PzlUXwnhirIst+cyAYyf5sA1GTQH
|
||||
uu/6MdoZ4+NTHb+1rq59j+v9wKTSHHhIPtI0zam5NByhNH5enGr306Fa9j1720ttuUQAE0tz4Epi/FJM
|
||||
cl24b8ZNd25KdTk31whg8mkOXEm4pX1EbS4LHebn5x+WdnIf765fr3NVCOFRuUwA00Nz4Gr21kX58lwW
|
||||
1qjmq8el+nxjqF4S4yVLS0sn5TIBTB/NgWuiOfAQTVE+J9XltnV16nXCvqqIF+cSAUw3zYGH5INnb9/+
|
||||
4Fyavtra7uRSLe4Zqk3f88MmxvNyjQBmhiavg/liVVVFrkuvLC4uPjSt/4eG6iEhXlOWZchlApg9mgNX
|
||||
c3P6wD8nl6UXqvlqZ1rv/xmqQ+/ThPJv5ufnH5TLBDC7NAeuZm97n/tclplWhfCstL4/GVr/nsf1fqCH
|
||||
NAeu5kB7aSSVZFabA13v786tVVFckGsE0C+aAw8mnSG/f25u7pRcmpnQbt8mlB/oWt8+pwnxWk+PBNAc
|
||||
uJoqxC/MSnNgs7BQ1yFc17WePc97Z+1AD+C4aA5czU3T/qjXdED3zLQePx5ar75nf77ev3VQJQBWaQ5c
|
||||
zZ4qhJfkskyVuigvapvbOtapt2lC/FFTls/IJQKgi+bA1aw0B07FGWOM8eQ6xnd1rEe/E+OX2jGdywTA
|
||||
fdEcuCYx/u2kXzNudjTz6az/c53L3+NUMX7YI6EBjp7mwIO5pt3J5rpMlHKhfFpavu8PLW/fM+s/7QTY
|
||||
eJoDV/PduiiWc1kmwuB6f7x7aDn7ntvrGC/MJQLgeGgOHKQK8Y46hOflsoxN0zQPbEJ8Z9cy9jxf3RnC
|
||||
o3OZABgFzYGrab9efl0qyViaAxcXFubSgchnOpar77k8xnhaLhMAo6Q5cE2K+L7NfoBMHcJT0nvfvG5Z
|
||||
+h3X+wE2iebAg7m6LMvtuS4bKl/v14txSMLuKoQX5BIBsBk0B64kfCfV4om5LCN33pYtD3DA1ZVwfb1Q
|
||||
PzaXCYDNpDlwJWH3RnSe75rbdUZ6/X9b/369z0eLojg9lwmAcdAcuJqV5sCRaEJ4QnrNbw+9R9+zcr1/
|
||||
26BKAIyV5sBDcll7W95cmmPSPocgvc6dQ6/b9+xpivJluUQATBDNgQdz1TE2B6phV4p446TdhAmAIens
|
||||
9ZXpQ1tz4KA58Am5LPfrrB07Hp7+zr90v1Z/UxXxU3Vdn5nLBMAk0xy4krC7WSifm8tyWGVZnl2F+M3u
|
||||
1+hxYrxkeXn5xFwmAKaB5sDV7E9nsRfnsqyTdnIvGtxiuPPv9jV7Ul1ekUsEwLTRHHgwVSjfsbS0dFIu
|
||||
TWtr+6uB9P8ODP/Znue7ZVmek2sEwBTT2Laa8sr2enb7jHoHRl0JV8QYH5nHDQCzwJ0DV/P1tKO7vuO/
|
||||
9zpVKN/qej/AjNIcKB3Z24TyVXmIADCrNAfKmtzUxHhuHhoAzDrNgZJyVQjhUXlIANAjmgN7m/Du471d
|
||||
MgBTzp0D+5Sw777uiQBAz2gO7EPCLSnn500OAAOaA2c615RlGfKmBoBDaQ6cvTQhvmd+fv5BeRMDwGFp
|
||||
DpyJuN4PwDHQHDjVubUqigvypgSAo6M5cPrShHjtYghl3oQAcGw0B05Rivi+ubm5U/KmA4Djozlw4rM/
|
||||
X+/fOthiADA6mgMnME2IP2rK8hl5GwHAxtAcOFH5SozxrLxpAGBjaQ4cf6oYP9w0zal5kwDA5tAcOLYc
|
||||
aC/FpE1wwmBLAMAm0xy46bk91fvCXH4AGCvNgZuRIn6tKYrH5JoDwGTQHLihuTzGeFouNQBMFs2BI4/r
|
||||
/QBMB82Bo0rYXYXwglxWAJh8mgOPN+H6eqF+bC4nAEwVzYHHkiL+c1EUp+caAsB00hx4FInxLalk2waV
|
||||
A4AppznwfrOnLsqX53IBwOzQHHiYFPHGaqF6Ui4TAMwezYGHpirip+q6PjOXBwBmmubANjFesry8fGKu
|
||||
CQD0Q4+bA/dWMf56LgMA9E8PmwO/W5blOXn1AaC/+tMcWF4ZY3xkXm0AYOabA2O8ZGlp6aS8ugDAGrPY
|
||||
HLi3CeWr8voBAIczQ82BN6UDmnPzagEA92f6mwPLz1dVVeTVAQCO1LQ2B1Yh/PX8/PyD8moAAEdrupoD
|
||||
w76qiBfnRQcAjtMUNAeGW1LOz8sLAIzKBDcHXlOWZciLCQCM2gQ2B142Nzd3Sl48AGCjTEhz4H7X+wFg
|
||||
k425OfDWqqh+Pi8KALDJtqWDgDemHfKBoR30hqUJ8dqY5PcHAMalKcrnpJ3z94Z31qNO+/t+1/sBYIKk
|
||||
k/LT6hD+Mu2oR/4rgXTW/+X02r+U3woAmDTtz/GaIv5F2nH/ZHhHfpS5J+Vf01n/S9LLbhu8OgAw0dpb
|
||||
8TYL5XPTmfvb0o78v/MOvWtHvybtzXzKT1Qx/n5d1wv5pQCAaXXvAUFRLLXd+3WMFzZF+cKUl7X/rIri
|
||||
gsWFhbn8RwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
|
||||
AAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
283
SCrawler.YouTube/Controls/MusicPlaylistsForm.vb
Normal file
@@ -0,0 +1,283 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports SCrawler.DownloadObjects.STDownloader
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Controls
|
||||
Imports PersonalUtilities.Forms.Controls.Base
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class MusicPlaylistsForm : Implements IDesignXMLContainer
|
||||
#Region "Declarations"
|
||||
Private MyView As FormView
|
||||
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
|
||||
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
|
||||
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
|
||||
Private ReadOnly MyContainer As IYouTubeMediaContainer
|
||||
Private Initializing As Boolean = True
|
||||
Private ReadOnly Property Current As IYouTubeMediaContainer
|
||||
Get
|
||||
With MyContainer
|
||||
If .ObjectType = Base.YouTubeMediaType.Channel Then
|
||||
If _LatestSelected.ValueBetween(0, .Count - 1) Then Return .Elements(_LatestSelected)
|
||||
Else
|
||||
Return .Self
|
||||
End If
|
||||
End With
|
||||
Return Nothing
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal Container As IYouTubeMediaContainer)
|
||||
InitializeComponent()
|
||||
MyContainer = Container
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Form handlers"
|
||||
Private Sub MusicPlaylistsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
If Not DesignXML Is Nothing Then
|
||||
MyView = New FormView(Me)
|
||||
MyView.Import()
|
||||
MyView.SetFormSize()
|
||||
End If
|
||||
|
||||
MyYouTubeSettings.DownloadLocations.PopulateComboBox(TXT_OUTPUT_PATH)
|
||||
|
||||
CMB_FORMATS.Items.AddRange(AvailableAudioFormats)
|
||||
If MyYouTubeSettings.PlaylistFormSplitterDistance > 0 Then SPLITTER_MAIN.SplitterDistancePercentageSet(MyYouTubeSettings.PlaylistFormSplitterDistance)
|
||||
|
||||
With MyContainer
|
||||
CH_DOWN_LYRICS.Checked = Not .OutputSubtitlesFormat.IsEmptyString
|
||||
Dim i%
|
||||
If Not .OutputAudioCodec.IsEmptyString Then
|
||||
i = AvailableAudioFormats.ListIndexOf(Function(ff) ff.StringToLower = .OutputAudioCodec.StringToLower)
|
||||
If i >= 0 Then CMB_FORMATS.SelectedIndex = i
|
||||
End If
|
||||
If CMB_FORMATS.SelectedIndex = -1 Then
|
||||
Dim oac$ = MyYouTubeSettings.DefaultAudioCodecMusic.Value.IfNullOrEmpty("mp3").StringToLower
|
||||
i = AvailableAudioFormats.ListIndexOf(Function(ff) ff.StringToLower = oac)
|
||||
If i >= 0 Then CMB_FORMATS.SelectedIndex = i Else CMB_FORMATS.SelectedIndex = 0
|
||||
End If
|
||||
|
||||
If .ObjectType = Base.YouTubeMediaType.Channel Then
|
||||
If .HasElements Then
|
||||
For Each elem In .Elements : LIST_PLAYLISTS.Items.Add(elem, elem.CheckState) : Next
|
||||
End If
|
||||
ElseIf .ObjectType = Base.YouTubeMediaType.PlayList Then
|
||||
LIST_PLAYLISTS.Items.Add(.Self, .CheckState)
|
||||
Else
|
||||
Throw New InvalidOperationException($"The object type '{ .ObjectType}' is incompatible with 'MusicPlaylistsForm'.")
|
||||
End If
|
||||
LIST_PLAYLISTS.SelectedIndex = 0
|
||||
|
||||
TXT_OUTPUT_PATH.Text = MyYouTubeSettings.OutputPath.Value
|
||||
|
||||
If Not .UserTitle.IsEmptyString Then
|
||||
Text = .UserTitle
|
||||
If .ObjectType = Base.YouTubeMediaType.PlayList Then
|
||||
If Not .PlaylistTitle.IsEmptyString AndAlso Not .PlaylistTitle = .UserTitle Then
|
||||
Text &= $" - { .PlaylistTitle}"
|
||||
ElseIf Not .Title.IsEmptyString AndAlso Not .Title = .UserTitle Then
|
||||
Text &= $" - { .Title}"
|
||||
End If
|
||||
End If
|
||||
If Not TXT_OUTPUT_PATH.IsEmptyString AndAlso Not TXT_OUTPUT_PATH.Text.Contains(.UserTitle) Then TXT_OUTPUT_PATH.Text = $"{TXT_OUTPUT_PATH.Text.TrimEnd("\")}\{ .UserTitle}\"
|
||||
ElseIf Not .PlaylistTitle.IsEmptyString Then
|
||||
Text = .PlaylistTitle
|
||||
End If
|
||||
|
||||
UpdateSizeText()
|
||||
End With
|
||||
RefillAddit()
|
||||
Initializing = False
|
||||
End Sub
|
||||
Private Sub MusicPlaylistsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||
MyYouTubeSettings.PlaylistFormSplitterDistance.Value = SPLITTER_MAIN.SplitterDistancePercentageGet
|
||||
MyView.DisposeIfReady()
|
||||
End Sub
|
||||
Private Sub MusicPlaylistsForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||
Dim b As Boolean = True
|
||||
If e.KeyCode = Keys.O And e.Control Then
|
||||
MyYouTubeSettings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT_PATH, False, MyDownloaderSettings.OutputPathAskForName)
|
||||
ElseIf e.KeyCode = Keys.O And e.Alt Then
|
||||
MyYouTubeSettings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT_PATH, True, MyDownloaderSettings.OutputPathAskForName)
|
||||
Else
|
||||
b = False
|
||||
End If
|
||||
If b Then e.Handled = True
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Form text"
|
||||
Private _InitialFormText As String = String.Empty
|
||||
Private Sub UpdateSizeText()
|
||||
If _InitialFormText.IsEmptyString Then _InitialFormText = Text
|
||||
Text = $"{_InitialFormText} ({MyContainer.SizeStr})"
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Settings"
|
||||
Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick, TXT_FORMATS_ADDIT.ActionOnButtonClick
|
||||
Dim isLyrics As Boolean = DirectCast(e.AssociatedControl, Control).Tag = "s"
|
||||
With DirectCast(MyContainer, YouTubeMediaContainerBase)
|
||||
Select Case Sender.DefaultButton
|
||||
Case ADB.Open
|
||||
Using f As New SimpleListForm(Of String)(IIf(isLyrics, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
|
||||
.DesignXML = DesignXML,
|
||||
.DesignXMLNodeName = SimpleArraysFormNode,
|
||||
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText,
|
||||
.Icon = My.Resources.SiteYouTube.YouTubeMusicIcon_32,
|
||||
.Mode = SimpleListFormModes.CheckedItems
|
||||
}
|
||||
f.DataSelected.ListAddList(IIf(isLyrics, .PostProcessing_OutputSubtitlesFormats, .PostProcessing_OutputAudioFormats))
|
||||
If f.ShowDialog = DialogResult.OK Then
|
||||
If isLyrics Then
|
||||
.PostProcessing_OutputSubtitlesFormats.Clear()
|
||||
.PostProcessing_OutputSubtitlesFormats.ListAddList(f.DataResult)
|
||||
Else
|
||||
.PostProcessing_OutputAudioFormats.Clear()
|
||||
.PostProcessing_OutputAudioFormats.ListAddList(f.DataResult)
|
||||
End If
|
||||
RefillAddit()
|
||||
End If
|
||||
End Using
|
||||
Case ADB.Refresh
|
||||
If isLyrics Then
|
||||
.PostProcessing_OutputSubtitlesFormats_Reset()
|
||||
Else
|
||||
.PostProcessing_OutputAudioFormats_Reset()
|
||||
End If
|
||||
RefillAddit()
|
||||
Case ADB.Clear
|
||||
If isLyrics Then
|
||||
.PostProcessing_OutputSubtitlesFormats.Clear()
|
||||
Else
|
||||
.PostProcessing_OutputAudioFormats.Clear()
|
||||
End If
|
||||
RefillAddit()
|
||||
End Select
|
||||
End With
|
||||
End Sub
|
||||
Private Sub RefillAddit()
|
||||
With DirectCast(MyContainer, YouTubeMediaContainerBase)
|
||||
TXT_SUBS.Text = .PostProcessing_OutputSubtitlesFormats.ListToString
|
||||
TXT_FORMATS_ADDIT.Text = .PostProcessing_OutputAudioFormats.ListToString
|
||||
End With
|
||||
End Sub
|
||||
Private Sub TXT_OUTPUT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_OUTPUT_PATH.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _
|
||||
MyYouTubeSettings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT_PATH, Sender.DefaultButton = ADB.Add, MyDownloaderSettings.OutputPathAskForName)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Lists' handlers"
|
||||
Private _LatestSelected As Integer = -1
|
||||
Private Sub LIST_PLAYLISTS_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_PLAYLISTS.SelectedIndexChanged
|
||||
Dim i% = LIST_PLAYLISTS.SelectedIndex
|
||||
If i >= 0 Then
|
||||
_LatestSelected = i
|
||||
LIST_ITEMS.Items.Clear()
|
||||
With DirectCast(LIST_PLAYLISTS.SelectedItem, IYouTubeMediaContainer)
|
||||
If .HasElements Then
|
||||
For Each elem In .Elements : LIST_ITEMS.Items.Add(elem, elem.Checked) : Next
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
Private _CheckHandlersSuspended As Boolean = False
|
||||
Private Sub LIST_PLAYLISTS_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles LIST_PLAYLISTS.ItemCheck
|
||||
If Not Initializing And Not _CheckHandlersSuspended Then
|
||||
_CheckHandlersSuspended = True
|
||||
|
||||
Dim checked As Boolean = Not e.NewValue = CheckState.Unchecked
|
||||
|
||||
Dim current As IYouTubeMediaContainer = Me.Current
|
||||
If Not current Is Nothing Then
|
||||
With current
|
||||
.Checked = checked
|
||||
If LIST_ITEMS.Items.Count > 0 Then
|
||||
_ListCheckHandlersSuspended = True
|
||||
For i% = 0 To .Count - 1
|
||||
If i.ValueBetween(0, LIST_ITEMS.Items.Count - 1) Then LIST_ITEMS.SetItemChecked(i, checked)
|
||||
Next
|
||||
_ListCheckHandlersSuspended = False
|
||||
End If
|
||||
If LIST_PLAYLISTS.Items.Count.ValueBetween(0, _LatestSelected) Then LIST_PLAYLISTS.SetItemChecked(_LatestSelected, checked)
|
||||
End With
|
||||
UpdateSizeText()
|
||||
End If
|
||||
|
||||
_CheckHandlersSuspended = False
|
||||
End If
|
||||
End Sub
|
||||
Private _ListCheckHandlersSuspended As Boolean = False
|
||||
Private Sub LIST_ITEMS_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles LIST_ITEMS.ItemCheck
|
||||
If Not Initializing Then
|
||||
Dim current As IYouTubeMediaContainer = Me.Current
|
||||
If Not current Is Nothing Then
|
||||
With current
|
||||
If e.Index.ValueBetween(0, .Count - 1) Then
|
||||
.Elements(e.Index).Checked = e.NewValue
|
||||
If Not _ListCheckHandlersSuspended And _LatestSelected.ValueBetween(0, LIST_PLAYLISTS.Items.Count - 1) Then
|
||||
Dim checked As Boolean = .Elements(e.Index).Checked
|
||||
_CheckHandlersSuspended = True
|
||||
If .Elements.All(Function(ee) ee.Checked = checked) Then
|
||||
LIST_PLAYLISTS.SetItemChecked(_LatestSelected, checked)
|
||||
Else
|
||||
LIST_PLAYLISTS.SetItemCheckState(_LatestSelected, CheckState.Indeterminate)
|
||||
End If
|
||||
_CheckHandlersSuspended = False
|
||||
LIST_PLAYLISTS.Refresh()
|
||||
UpdateSizeText()
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Selection buttons"
|
||||
Private Sub BTT_PLS_Click(sender As Object, e As EventArgs) Handles BTT_PLS_ALL.Click, BTT_PLS_NONE.Click
|
||||
Dim checked As Boolean = DirectCast(sender, Button).Tag = "a"
|
||||
_CheckHandlersSuspended = True
|
||||
If LIST_PLAYLISTS.Items.Count > 0 Then
|
||||
For i% = 0 To LIST_PLAYLISTS.Items.Count - 1 : LIST_PLAYLISTS.SetItemChecked(i, checked) : Next
|
||||
End If
|
||||
MyContainer.Checked = checked
|
||||
If MyContainer.Count > 1 Then MyContainer.Elements.ForEach(Sub(ee) ee.Checked = checked)
|
||||
_CheckHandlersSuspended = False
|
||||
UpdateSizeText()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Ok, Cancel"
|
||||
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
||||
If TXT_OUTPUT_PATH.IsEmptyString Then
|
||||
MsgBoxE({"The output path cannot be null.", "Download music"}, vbCritical)
|
||||
Else
|
||||
With DirectCast(MyContainer, YouTubeMediaContainerBase)
|
||||
.OutputSubtitlesFormat = IIf(CH_DOWN_LYRICS.Checked, "LRC", String.Empty)
|
||||
If Not TXT_SUBS.Checked Then .PostProcessing_OutputSubtitlesFormats.Clear()
|
||||
.OutputAudioCodec = CMB_FORMATS.Text
|
||||
If Not TXT_FORMATS_ADDIT.Checked Then .PostProcessing_OutputAudioFormats.Clear()
|
||||
.File = TXT_OUTPUT_PATH.Text.CSFileP
|
||||
If MyYouTubeSettings.OutputPathAutoChange Then MyYouTubeSettings.OutputPath.Value = .File
|
||||
If MyDownloaderSettings.OutputPathAutoAddPaths Then MyYouTubeSettings.DownloadLocations.Add(.File, False)
|
||||
End With
|
||||
DialogResult = DialogResult.OK
|
||||
Close()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub BTT_CANCEL_Click(sender As Object, e As EventArgs) Handles BTT_CANCEL.Click
|
||||
DialogResult = DialogResult.Cancel
|
||||
Close()
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
93
SCrawler.YouTube/Controls/ParsingProgressForm.Designer.vb
generated
Normal file
@@ -0,0 +1,93 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Public Class ParsingProgressForm : 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 TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Me.PR_MAIN = New System.Windows.Forms.ProgressBar()
|
||||
Me.LBL_MAIN = New System.Windows.Forms.Label()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_MAIN.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'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.PR_MAIN, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.LBL_MAIN, 0, 1)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Margin = New System.Windows.Forms.Padding(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, 25.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(334, 56)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'PR_MAIN
|
||||
'
|
||||
Me.PR_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.PR_MAIN.Location = New System.Drawing.Point(3, 3)
|
||||
Me.PR_MAIN.Name = "PR_MAIN"
|
||||
Me.PR_MAIN.Size = New System.Drawing.Size(328, 25)
|
||||
Me.PR_MAIN.TabIndex = 0
|
||||
'
|
||||
'LBL_MAIN
|
||||
'
|
||||
Me.LBL_MAIN.AutoSize = True
|
||||
Me.LBL_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_MAIN.Location = New System.Drawing.Point(3, 31)
|
||||
Me.LBL_MAIN.Name = "LBL_MAIN"
|
||||
Me.LBL_MAIN.Size = New System.Drawing.Size(328, 25)
|
||||
Me.LBL_MAIN.TabIndex = 1
|
||||
Me.LBL_MAIN.TextAlign = System.Drawing.ContentAlignment.TopCenter
|
||||
'
|
||||
'ParsingProgressForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(334, 56)
|
||||
Me.ControlBox = False
|
||||
Me.Controls.Add(TP_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(350, 95)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(350, 95)
|
||||
Me.Name = "ParsingProgressForm"
|
||||
Me.ShowIcon = False
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
|
||||
Me.Text = "Parsing progress"
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_MAIN.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents PR_MAIN As ProgressBar
|
||||
Private WithEvents LBL_MAIN As Label
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -117,9 +117,6 @@
|
||||
<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>
|
||||
66
SCrawler.YouTube/Controls/ParsingProgressForm.vb
Normal file
@@ -0,0 +1,66 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Threading
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Namespace API.YouTube.Controls
|
||||
Public Class ParsingProgressForm
|
||||
Public ReadOnly Property MyProgress As MyProgress
|
||||
Private ReadOnly TokenSource As CancellationTokenSource
|
||||
Public ReadOnly Property Token As CancellationToken
|
||||
Get
|
||||
Return TokenSource.Token
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly CountMax As Integer
|
||||
Private CountCurrent As Integer = 1
|
||||
Friend Sub NextPlaylist()
|
||||
CountCurrent += 1
|
||||
MyProgress.InformationTemporary(True) = InfoStr
|
||||
MyProgress.Information = InfoStr
|
||||
End Sub
|
||||
Private ReadOnly Property InfoStr As String
|
||||
Get
|
||||
Const MainMsg$ = "Data parsing in progress"
|
||||
If CountMax > 1 Then
|
||||
Return $"{MainMsg} [{CountCurrent - 1}/{CountMax}]"
|
||||
Else
|
||||
Return MainMsg
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Public Sub New(Optional ByVal _Count As Integer = 1)
|
||||
InitializeComponent()
|
||||
CountMax = _Count
|
||||
MyProgress = New MyProgress(PR_MAIN, LBL_MAIN, InfoStr) With {.ResetProgressOnMaximumChanges = False}
|
||||
TokenSource = New CancellationTokenSource
|
||||
End Sub
|
||||
Public Sub SetInitialValues(ByVal Count As Integer, ByVal Info As String)
|
||||
With MyProgress
|
||||
.Maximum = Count
|
||||
.Visible = True
|
||||
.Perform(0.5)
|
||||
.Value = 0
|
||||
.InformationTemporary = Info
|
||||
End With
|
||||
End Sub
|
||||
Private _KeyDownDisabled As Boolean = False
|
||||
Private Sub ParsingProgressForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||
If e.KeyCode = Keys.Escape AndAlso Not _KeyDownDisabled AndAlso MsgBoxE({"Data parsing in progress." & vbCr &
|
||||
"Are you sure you want to stop parsing and cancel the operation?",
|
||||
"Stop parsing"}, vbExclamation + vbYesNo) = vbYes Then
|
||||
_KeyDownDisabled = True
|
||||
TokenSource.Cancel()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ParsingProgressForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
MyProgress.Dispose()
|
||||
TokenSource.Dispose()
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
171
SCrawler.YouTube/Controls/PlayListParserForm.Designer.vb
generated
Normal file
@@ -0,0 +1,171 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class PlayListParserForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim FRM_IN As System.Windows.Forms.GroupBox
|
||||
Dim FRM_OUT As System.Windows.Forms.GroupBox
|
||||
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(PlayListParserForm))
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.TXT_IN = New System.Windows.Forms.RichTextBox()
|
||||
Me.TXT_OUT = New System.Windows.Forms.RichTextBox()
|
||||
Me.TXT_LIMIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
FRM_IN = New System.Windows.Forms.GroupBox()
|
||||
FRM_OUT = New System.Windows.Forms.GroupBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
TP_MAIN.SuspendLayout()
|
||||
FRM_IN.SuspendLayout()
|
||||
FRM_OUT.SuspendLayout()
|
||||
CType(Me.TXT_LIMIT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'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(FRM_IN, 0, 1)
|
||||
TP_MAIN.Controls.Add(FRM_OUT, 0, 2)
|
||||
TP_MAIN.Controls.Add(Me.TXT_LIMIT, 0, 0)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Margin = New System.Windows.Forms.Padding(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.Percent, 50.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(384, 261)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'FRM_IN
|
||||
'
|
||||
FRM_IN.Controls.Add(Me.TXT_IN)
|
||||
FRM_IN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
FRM_IN.Location = New System.Drawing.Point(3, 31)
|
||||
FRM_IN.Name = "FRM_IN"
|
||||
FRM_IN.Size = New System.Drawing.Size(378, 110)
|
||||
FRM_IN.TabIndex = 0
|
||||
FRM_IN.TabStop = False
|
||||
FRM_IN.Text = "In"
|
||||
TT_MAIN.SetToolTip(FRM_IN, "In your browser's DevTools, find the page starting with the following URL and cop" &
|
||||
"y the response text into this window." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "https://music.youtube.com/youtubei/v1/bro" &
|
||||
"wse?key=")
|
||||
'
|
||||
'TXT_IN
|
||||
'
|
||||
Me.TXT_IN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_IN.Location = New System.Drawing.Point(3, 16)
|
||||
Me.TXT_IN.Name = "TXT_IN"
|
||||
Me.TXT_IN.Size = New System.Drawing.Size(372, 91)
|
||||
Me.TXT_IN.TabIndex = 0
|
||||
Me.TXT_IN.Text = ""
|
||||
'
|
||||
'FRM_OUT
|
||||
'
|
||||
FRM_OUT.Controls.Add(Me.TXT_OUT)
|
||||
FRM_OUT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
FRM_OUT.Location = New System.Drawing.Point(3, 147)
|
||||
FRM_OUT.Name = "FRM_OUT"
|
||||
FRM_OUT.Size = New System.Drawing.Size(378, 111)
|
||||
FRM_OUT.TabIndex = 1
|
||||
FRM_OUT.TabStop = False
|
||||
FRM_OUT.Text = "Out"
|
||||
'
|
||||
'TXT_OUT
|
||||
'
|
||||
Me.TXT_OUT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_OUT.Location = New System.Drawing.Point(3, 16)
|
||||
Me.TXT_OUT.Name = "TXT_OUT"
|
||||
Me.TXT_OUT.Size = New System.Drawing.Size(372, 92)
|
||||
Me.TXT_OUT.TabIndex = 0
|
||||
Me.TXT_OUT.Text = ""
|
||||
'
|
||||
'TXT_LIMIT
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Name = "Clear"
|
||||
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_LIMIT.Buttons.Add(ActionButton1)
|
||||
Me.TXT_LIMIT.CaptionText = "Remove"
|
||||
Me.TXT_LIMIT.CaptionToolTipEnabled = True
|
||||
Me.TXT_LIMIT.CaptionToolTipText = "Remove playlists starts with..."
|
||||
Me.TXT_LIMIT.CaptionWidth = 50.0R
|
||||
Me.TXT_LIMIT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_LIMIT.Location = New System.Drawing.Point(3, 3)
|
||||
Me.TXT_LIMIT.Name = "TXT_LIMIT"
|
||||
Me.TXT_LIMIT.PlaceholderEnabled = True
|
||||
Me.TXT_LIMIT.PlaceholderText = "e.g. ABCDE"
|
||||
Me.TXT_LIMIT.Size = New System.Drawing.Size(378, 22)
|
||||
Me.TXT_LIMIT.TabIndex = 2
|
||||
'
|
||||
'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
|
||||
'
|
||||
'PlayListParserForm
|
||||
'
|
||||
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.SiteYouTube.YouTubeMusicIcon_32
|
||||
Me.KeyPreview = True
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(400, 300)
|
||||
Me.Name = "PlayListParserForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.Text = "Playlist parser"
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
FRM_IN.ResumeLayout(False)
|
||||
FRM_OUT.ResumeLayout(False)
|
||||
CType(Me.TXT_LIMIT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents TXT_IN As RichTextBox
|
||||
Private WithEvents TXT_OUT As RichTextBox
|
||||
Private WithEvents TXT_LIMIT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -117,14 +117,23 @@
|
||||
<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="FRM_IN.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>
|
||||
<metadata name="FRM_OUT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
@@ -132,24 +141,7 @@
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
60
SCrawler.YouTube/Controls/PlayListParserForm.vb
Normal file
@@ -0,0 +1,60 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class PlayListParserForm : Implements IDesignXMLContainer
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
|
||||
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
|
||||
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
|
||||
Friend ReadOnly Property PlayLists As List(Of String)
|
||||
Get
|
||||
If Not TXT_OUT.Text.IsEmptyString Then
|
||||
Return TXT_OUT.Lines.ToList
|
||||
Else
|
||||
Return New List(Of String)
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub New()
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormOptions(Me)
|
||||
End Sub
|
||||
Private Sub MyForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
With MyDefs
|
||||
.MyViewInitialize()
|
||||
.AddOkCancelToolbar()
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
End Sub
|
||||
Private Sub UpdatePlaylists(sender As Object, e As EventArgs) Handles TXT_IN.TextChanged, TXT_LIMIT.ActionOnTextChanged
|
||||
Try
|
||||
If Not TXT_IN.Text.IsEmptyString Then
|
||||
Dim l As List(Of String) = ListAddList(Of String)(Nothing, RegexReplace(TXT_IN.Text, RParams.DMS("playlistId"": ""([^""]+)""", 1,
|
||||
RegexReturn.List, EDP.ReturnValue)),
|
||||
LAP.NotContainsOnly, EDP.ReturnValue)
|
||||
If Not TXT_LIMIT.Text.IsEmptyString And l.ListExists Then l.RemoveAll(Function(id) id.StringToLower.StartsWith(TXT_LIMIT.Text.ToLower))
|
||||
If l.ListExists Then
|
||||
TXT_OUT.Text = l.Select(Function(id) $"https://music.youtube.com/playlist?list={id}").ListToString(vbNewLine, EDP.ReturnValue)
|
||||
Else
|
||||
TXT_OUT.Text = String.Empty
|
||||
End If
|
||||
Else
|
||||
TXT_OUT.Text = String.Empty
|
||||
End If
|
||||
Catch ex As Exception
|
||||
TXT_OUT.Text = String.Empty
|
||||
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "[PlayListParserForm.UpdatePlaylists]")
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -6,9 +6,9 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.PornHub
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class OptionsForm : Inherits System.Windows.Forms.Form
|
||||
Partial Friend Class PlaylistArrayForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
@@ -24,13 +24,16 @@ Namespace API.PornHub
|
||||
Private Sub InitializeComponent()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Me.CH_DOWN_GIFS = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_DOWN_PHOTO_MODELHUB = New System.Windows.Forms.CheckBox()
|
||||
Dim FRM_PLS As System.Windows.Forms.GroupBox
|
||||
Me.CH_PLS_ONE = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_URLS = New System.Windows.Forms.RichTextBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
FRM_PLS = New System.Windows.Forms.GroupBox()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
FRM_PLS.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
@@ -39,80 +42,87 @@ Namespace API.PornHub
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(278, 52)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 311)
|
||||
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(278, 77)
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 311)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
TP_MAIN.ColumnCount = 1
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Controls.Add(Me.CH_DOWN_GIFS, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.CH_DOWN_PHOTO_MODELHUB, 0, 1)
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_MAIN.Controls.Add(Me.CH_PLS_ONE, 0, 0)
|
||||
TP_MAIN.Controls.Add(FRM_PLS, 0, 1)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 3
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_MAIN.RowCount = 2
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(278, 52)
|
||||
TP_MAIN.Size = New System.Drawing.Size(384, 311)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'CH_DOWN_GIFS
|
||||
'CH_PLS_ONE
|
||||
'
|
||||
Me.CH_DOWN_GIFS.AutoSize = True
|
||||
Me.CH_DOWN_GIFS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_GIFS.Location = New System.Drawing.Point(4, 4)
|
||||
Me.CH_DOWN_GIFS.Name = "CH_DOWN_GIFS"
|
||||
Me.CH_DOWN_GIFS.Size = New System.Drawing.Size(270, 19)
|
||||
Me.CH_DOWN_GIFS.TabIndex = 0
|
||||
Me.CH_DOWN_GIFS.Text = "Download gifs"
|
||||
Me.CH_DOWN_GIFS.UseVisualStyleBackColor = True
|
||||
Me.CH_PLS_ONE.AutoSize = True
|
||||
Me.CH_PLS_ONE.Checked = True
|
||||
Me.CH_PLS_ONE.CheckState = System.Windows.Forms.CheckState.Checked
|
||||
Me.CH_PLS_ONE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_PLS_ONE.Location = New System.Drawing.Point(3, 3)
|
||||
Me.CH_PLS_ONE.Name = "CH_PLS_ONE"
|
||||
Me.CH_PLS_ONE.Size = New System.Drawing.Size(378, 19)
|
||||
Me.CH_PLS_ONE.TabIndex = 1
|
||||
Me.CH_PLS_ONE.Text = "Playlists / Albums by one artist"
|
||||
Me.CH_PLS_ONE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_DOWN_PHOTO_MODELHUB
|
||||
'FRM_PLS
|
||||
'
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.AutoSize = True
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.Location = New System.Drawing.Point(4, 30)
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.Name = "CH_DOWN_PHOTO_MODELHUB"
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.Size = New System.Drawing.Size(270, 19)
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.TabIndex = 1
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.Text = "Download photo only from ModelHub"
|
||||
Me.CH_DOWN_PHOTO_MODELHUB.UseVisualStyleBackColor = True
|
||||
FRM_PLS.Controls.Add(Me.TXT_URLS)
|
||||
FRM_PLS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
FRM_PLS.Location = New System.Drawing.Point(3, 28)
|
||||
FRM_PLS.Name = "FRM_PLS"
|
||||
FRM_PLS.Size = New System.Drawing.Size(378, 280)
|
||||
FRM_PLS.TabIndex = 0
|
||||
FRM_PLS.TabStop = False
|
||||
FRM_PLS.Text = "URLs (new line as delimiter); Ctrl+O to parse playlists from response"
|
||||
'
|
||||
'OptionsForm
|
||||
'TXT_URLS
|
||||
'
|
||||
Me.TXT_URLS.DetectUrls = False
|
||||
Me.TXT_URLS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_URLS.Location = New System.Drawing.Point(3, 16)
|
||||
Me.TXT_URLS.Name = "TXT_URLS"
|
||||
Me.TXT_URLS.Size = New System.Drawing.Size(372, 261)
|
||||
Me.TXT_URLS.TabIndex = 0
|
||||
Me.TXT_URLS.Text = ""
|
||||
'
|
||||
'PlaylistArrayForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(278, 77)
|
||||
Me.ClientSize = New System.Drawing.Size(384, 311)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteResources.InstagramIcon_32
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeMusicIcon_32
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(294, 116)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(294, 116)
|
||||
Me.Name = "OptionsForm"
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
Me.Text = "Options"
|
||||
Me.MinimumSize = New System.Drawing.Size(400, 350)
|
||||
Me.Name = "PlaylistArrayForm"
|
||||
Me.Text = "Playlists / Albums"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_MAIN.PerformLayout()
|
||||
FRM_PLS.ResumeLayout(False)
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents CH_DOWN_GIFS As CheckBox
|
||||
Private WithEvents CH_DOWN_PHOTO_MODELHUB As CheckBox
|
||||
Private WithEvents CH_PLS_ONE As CheckBox
|
||||
Private WithEvents TXT_URLS As RichTextBox
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -123,4 +123,7 @@
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="FRM_PLS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
54
SCrawler.YouTube/Controls/PlaylistArrayForm.vb
Normal file
@@ -0,0 +1,54 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class PlaylistArrayForm : Implements IDesignXMLContainer
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
|
||||
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
|
||||
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
|
||||
Friend ReadOnly Property URLs As List(Of String)
|
||||
Get
|
||||
If Not TXT_URLS.Text.IsEmptyString Then
|
||||
Return ListAddList(Nothing, TXT_URLS.Text.StringFormatLines.StringToList(Of String)(vbNewLine),
|
||||
LAP.NotContainsOnly, EDP.ReturnValue, CType(Function(Input$) Input.StringTrim, Func(Of Object, Object))).ListIfNothing
|
||||
Else
|
||||
Return New List(Of String)
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property IsOneArtist As Boolean
|
||||
Get
|
||||
Return CH_PLS_ONE.Checked
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub New()
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormOptions(Me)
|
||||
End Sub
|
||||
Private Sub PlaylistArrayForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
With MyDefs
|
||||
.MyViewInitialize()
|
||||
.AddOkCancelToolbar()
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
End Sub
|
||||
Private Sub PlaylistArrayForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||
If e.KeyCode = Keys.O And e.Control Then
|
||||
Using f As New PlayListParserForm With {.DesignXML = DesignXML}
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK Then TXT_URLS.Text = f.PlayLists.ListToString(vbNewLine, EDP.ReturnValue)
|
||||
End Using
|
||||
e.Handled = True
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
132
SCrawler.YouTube/Controls/VideoOption.Designer.vb
generated
Normal file
@@ -0,0 +1,132 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class VideoOption : Inherits System.Windows.Forms.UserControl
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Me.OPT_CHECKED = New System.Windows.Forms.RadioButton()
|
||||
Me.LBL_DEFINITION_INFO = New System.Windows.Forms.Label()
|
||||
Me.LBL_DEFINITION = New System.Windows.Forms.Label()
|
||||
Me.LBL_CODECS = New System.Windows.Forms.Label()
|
||||
Me.LBL_SIZE = New System.Windows.Forms.Label()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_MAIN.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.ColumnCount = 5
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 36.0!))
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 110.0!))
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 58.0!))
|
||||
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, 71.0!))
|
||||
TP_MAIN.Controls.Add(Me.OPT_CHECKED, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.LBL_DEFINITION_INFO, 1, 0)
|
||||
TP_MAIN.Controls.Add(Me.LBL_DEFINITION, 2, 0)
|
||||
TP_MAIN.Controls.Add(Me.LBL_CODECS, 3, 0)
|
||||
TP_MAIN.Controls.Add(Me.LBL_SIZE, 4, 0)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 1
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(459, 30)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'OPT_CHECKED
|
||||
'
|
||||
Me.OPT_CHECKED.AutoSize = True
|
||||
Me.OPT_CHECKED.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
|
||||
Me.OPT_CHECKED.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_CHECKED.Location = New System.Drawing.Point(3, 3)
|
||||
Me.OPT_CHECKED.Name = "OPT_CHECKED"
|
||||
Me.OPT_CHECKED.Size = New System.Drawing.Size(30, 24)
|
||||
Me.OPT_CHECKED.TabIndex = 0
|
||||
Me.OPT_CHECKED.TabStop = True
|
||||
Me.OPT_CHECKED.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
|
||||
Me.OPT_CHECKED.UseVisualStyleBackColor = True
|
||||
'
|
||||
'LBL_DEFINITION_INFO
|
||||
'
|
||||
Me.LBL_DEFINITION_INFO.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_DEFINITION_INFO.Font = New System.Drawing.Font("Arial", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
|
||||
Me.LBL_DEFINITION_INFO.Location = New System.Drawing.Point(39, 0)
|
||||
Me.LBL_DEFINITION_INFO.Name = "LBL_DEFINITION_INFO"
|
||||
Me.LBL_DEFINITION_INFO.Size = New System.Drawing.Size(104, 30)
|
||||
Me.LBL_DEFINITION_INFO.TabIndex = 1
|
||||
Me.LBL_DEFINITION_INFO.Text = "Ultra High Definition"
|
||||
Me.LBL_DEFINITION_INFO.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
|
||||
'
|
||||
'LBL_DEFINITION
|
||||
'
|
||||
Me.LBL_DEFINITION.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_DEFINITION.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
|
||||
Me.LBL_DEFINITION.Location = New System.Drawing.Point(149, 0)
|
||||
Me.LBL_DEFINITION.Name = "LBL_DEFINITION"
|
||||
Me.LBL_DEFINITION.Size = New System.Drawing.Size(52, 30)
|
||||
Me.LBL_DEFINITION.TabIndex = 2
|
||||
Me.LBL_DEFINITION.Text = "1080p"
|
||||
Me.LBL_DEFINITION.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
|
||||
'
|
||||
'LBL_CODECS
|
||||
'
|
||||
Me.LBL_CODECS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_CODECS.Font = New System.Drawing.Font("Arial", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
|
||||
Me.LBL_CODECS.Location = New System.Drawing.Point(207, 0)
|
||||
Me.LBL_CODECS.Name = "LBL_CODECS"
|
||||
Me.LBL_CODECS.Size = New System.Drawing.Size(178, 30)
|
||||
Me.LBL_CODECS.TabIndex = 3
|
||||
Me.LBL_CODECS.Text = "MKV - VP9 - Opus"
|
||||
Me.LBL_CODECS.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
'
|
||||
'LBL_SIZE
|
||||
'
|
||||
Me.LBL_SIZE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_SIZE.Font = New System.Drawing.Font("Arial", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
|
||||
Me.LBL_SIZE.Location = New System.Drawing.Point(391, 0)
|
||||
Me.LBL_SIZE.Name = "LBL_SIZE"
|
||||
Me.LBL_SIZE.Size = New System.Drawing.Size(65, 30)
|
||||
Me.LBL_SIZE.TabIndex = 4
|
||||
Me.LBL_SIZE.Text = "1 062 MB"
|
||||
Me.LBL_SIZE.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
'
|
||||
'VideoOption
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.Controls.Add(TP_MAIN)
|
||||
Me.Name = "VideoOption"
|
||||
Me.Size = New System.Drawing.Size(459, 30)
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_MAIN.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents OPT_CHECKED As RadioButton
|
||||
Private WithEvents LBL_DEFINITION_INFO As Label
|
||||
Private WithEvents LBL_DEFINITION As Label
|
||||
Private WithEvents LBL_CODECS As Label
|
||||
Private WithEvents LBL_SIZE As Label
|
||||
End Class
|
||||
End Namespace
|
||||
123
SCrawler.YouTube/Controls/VideoOption.resx
Normal file
@@ -0,0 +1,123 @@
|
||||
<?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="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||