Compare commits

...

13 Commits

Author SHA1 Message Date
Andy
b42832719f 2024.11.21.0
API.Instagram: code refactoring (settings); add setting to skip errors; add 'ForceUpdateUserName' and 'ForceUpdateUserInfo' properties; add 'IgnoreStoriesDownloadingErrors' to the settings; improve username update algorithm
API.OnlyFans: add 'UpdateRules401' property; update the code to handle error 401
API.YouTube: 404 error handling (community)
UserDataBase: raise event to update user in exceptions; add extra buttons for special download (limited and dated)
UserDataBind: extra buttons (UserDataBase)
UserCreatorForm: fix network paths
GlobalSettingsForm, MainFrame, SettingsCLS: add ability to change the feed opening shortcut
MainFrame: update button captions, update 'DownloadSelectedUser' function
2024-11-21 17:50:19 +03:00
Andy
aedcebc781 2024.10.24.0
YT
YouTubeSettings: add 'DefaultVideoAllowWebm' and 'DefaultAudioEmbedThumbnail_Cover' settings
YouTubeMediaContainerBase: change cover selection for music download; fix adding incorrect playlist lines; allow 'webm' formats is there are no 'mp4' formats via http protocol

SCrawler
DeclaredNames: add new names
UserDataBase: add '_ForceSaveUserInfoOnException' field  and 'UpdateUserInformation_Ex' function to update user info on exception; clear '_MD5List' when clearing data and/or history
API.Instagram: add manual 'UserName' changing; mark user as non-existent if user ID cannot be obtained
API.Twitter: add manual 'UserName' changing
API.Mastodon: bypass inherited property
API.Reddit: fix incorrect UNIX date parsing
DownloadFeedForm: add exception handling to the 'RefillAfterDelete' function
MainFrame: add 'MENU_INFO_USER_SEARCH' to the 'Info' menu
SettingsHostCollection: fix a bug when changing data paths
2024-10-24 19:18:29 +03:00
Andy
00a06d3e9a 2024.9.2.0
Instagram: add options to enable/disable image extraction from video
OnlyFans: update to the changed API
YouTube: videos are parsed from the 'featured', not from the 'videos' page
Feed: add prompt before moving entire feed/session
MainFrame: add 'Alt+U' and 'Ctrl+U' to open the user search form
UserImage: user image creation update
2024-09-02 18:22:11 +03:00
Andy
2055461829 Update FAQ.md 2024-08-14 13:12:25 +03:00
Andy
723155e20c Update FAQ.md 2024-08-14 12:27:05 +03:00
Andy
effaa3b65b Update FAQ 2024-08-14 11:45:00 +03:00
Andy
e285de10f6 2024.8.10.0
YT
Fix bug when video is parsed using cookies but not downloaded

SCrawler
Feed: add a button to open file folder
2024-08-10 13:36:31 +03:00
Andy
26db0e3e24 2024.8.1.0
Feed: add the ability to set PostUrl for data when moving a file and/or adding to a feed
TDownloader: add 'PostUrl' property to 'UserMediaD'
2024-08-01 20:41:51 +03:00
Andy
0b0933b6f0 2024.7.24.0
YT
YouTubeSettings: add 'DefaultVideoConvertNonAVC' property; fix 'OpenFolderInOtherProgram' property serialize and reset; add 'MusicPlaylistCreate_CreationMode' property
Update the 'CleanFileName' function to remove line breaks
Add the ability to convert non-avc codecs to avc
Add 'M3U8CreationMode' enum

SCrawler
API.OnlyFans: fix incorrect delimiter (rules parsing)
API.Threads: add saved posts downloading
Feed: add the hotkeys 'Esc' and 'Ctrl+W' to close the form; add the ability to search for missing files in special feeds
Scheduler: add the ability to execute a script after the scheduler plan is executed
Settings: add enable/disable the use of the 'Esc' to close the feed; add 'AutomationScript' and 'AutomationScript_ExcludeManual' properties
MainFrame: add the hotkey 'Ctrl+F' to show the feed; change the hotkey from 'Ctrl+F' to 'Alt+F' to show the search form
2024-07-24 23:40:53 +03:00
Andy
3ce9c55575 Update OF DynamicRules 2024-07-08 22:35:28 +03:00
Andy
ef36a11566 Update OF DynamicRules 2024-07-07 09:36:10 +03:00
Andy
dea14d35af 2024.6.25.0
API.OnlyFans: new dynamic rules updating algo
API.Instagram: update settings
Feed: add ability to set the last session as the current one; wrong marking data as saved posts when moving a file
2024-06-25 11:46:33 +03:00
Andy
744698c99e 2024.6.13.0
Remove compatibility of settings of older versions
2024-06-13 12:16:38 +03:00
74 changed files with 3249 additions and 1014 deletions

View File

@@ -1,17 +1,14 @@
# Contributor's Guide # Contributor's Guide
I welcome requests! Follow these steps to contribute: Follow these steps to contribute:
1. Find an [issue](https://github.com/AAndyProgram/SCrawler/issues) that needs assistance. 1. Find an [issue](https://github.com/AAndyProgram/SCrawler/issues) that needs assistance.
1. Let me know you are working on it by posting a comment on the issue. 1. Let me know you're working on this by posting a comment on this issue.
1. If you find an error in the code, please provide a link to the file and the line number. 1. If you find a bug in the code, please provide a link to the file and line number.
1. If you have a code change suggestion, you can post a replacement code block.<!-- I also accept pull requests.--> 1. If you have a code change suggestion, you can post a replacement code block.<!-- I also accept pull requests.-->
# How to report a problem # How to report a problem
1. Attach the **profile URLs or links** that you cannot download.
1. Attach the **LOG** if it exists. **[Read here](https://github.com/AAndyProgram/SCrawler/blob/main/FAQ.md#how-to-report-a-problem)**
1. **Attach the environment information copied from SCrawler (click the top right info button in the main window, then the `Environment` button, then the `Copy` button, and paste the copied text into the issue).**
1. *Add screenshots to illustrate the problem (**optional**)*
# How to build from source # How to build from source
1. Delete the `PersonalUtilities` project from the solution. 1. Delete the `PersonalUtilities` project from the solution.
@@ -30,7 +27,7 @@ I welcome requests! Follow these steps to contribute:
**I'm currently not accepting requests to develop new sites.** **I'm currently not accepting requests to develop new sites.**
1. Check [issues](https://github.com/AAndyProgram/SCrawler/issues) (open and [closed](https://github.com/AAndyProgram/SCrawler/issues?q=is%3Aissue+is%3Aclosed)) and [discussions](https://github.com/AAndyProgram/SCrawler/discussions) to find your issue. Perhaps I have already answered your request. 1. Check [issues](https://github.com/AAndyProgram/SCrawler/issues) (open and [closed](https://github.com/AAndyProgram/SCrawler/issues?q=is%3Aissue+is%3Aclosed)) and [discussions](https://github.com/AAndyProgram/SCrawler/discussions) to find your issue. Perhaps I have already answered your request.
1. If you don't find anything, create a new issue with your request. I usually reply as soon as possible (within the next few hours). 1. If you don't find anything, create a new issue with your request.
# Requirements for new site requests # Requirements for new site requests

View File

@@ -1,3 +1,125 @@
# 2024.11.21.0
*2024-11-21*
- Added
- Sites:
- Instagram:
- setting to skip errors without disabling download *(site settings)*
- settings to force update of username and/or user information *(user settings)*
- setting to continue downloading profile if error 560 occurs while downloading user stories *(site settings)*
- improve username update algorithm
- YouTube: 404 error handling (community)
- Main window: add extra buttons for special download (limited and dated) in collection
- Global settings: ability to change the feed opening shortcut (`Ctrl+F`/`Alt+F` *(Settings - Behavior)*)
- Minor improvements
- Updated
- yt-dlp up to version **2024.11.18**
- gallery-dl up to version **1.27.7**
- Fixed
- Users: network paths aren't working
- Main window: in some cases users are not updated in the list
- Minor bugs
# 2024.10.24.0
*2024-10-24*
- Added
- YouTube (standalone app):
- settings `Embed thumbnail (cover)` and `Allow webm formats`
- changed cover selection for music downloads
- allow `webm` formats if there are no `mp4` formats via http protocol (issue #211)
- Sites:
- Instagram:
- **ability to manually change username**
- **mark user as non-existent if user `ID` cannot be obtained**
- Twitter: **ability to manually change username**
- Main window: add users search button to 'Info' menu
- Minor improvements
- Updated
- yt-dlp up to version **2024.10.22**
- gallery-dl up to version **1.27.6**
- Fixed
- YouTube (standalone app): adding incorrect playlist lines
- Reddit: incorrect UNIX date parsing
- Can't change data path (issue #206)
- Minor bugs
# 2024.9.2.0
*2024-09-02*
- Added
- Instagram: options to enable/disable image extraction from video
- Feed: **prompt before moving entire feed/session**
- Main window: hotkeys `Alt+U` and `Ctrl+U` to open the user search form
- Minor improvements
- Updated
- gallery-dl up to version **1.27.3**
- Fixed
- **OnlyFans**: data is not downloading
- YouTube (SCrawler): incorrect parsing of video page
- Minor bugs
# 2024.8.10.0
*2024-08-10*
- Added
- Feed: button to open file folder
- Updated
- yt-dlp up to version **2024.08.06**
- gallery-dl up to version **1.27.2**
- Fixed
- YouTube (standalone app): **video is being parsed using cookies but is not downloading** *(Issue #205)*
# 2024.8.1.0
*2024-08-01*
- Added
- Minor improvements
- Updated
- yt-dlp up to version **2024.08.01**
# 2024.7.24.0
*2024-07-24*
- Added
- YouTube (standalone app)
- ability to convert non-`AVC` codecs (eg `VP9`) to `AVC` (`Settings` - `Defaults Video` - `Convert non-AVC codecs to AVC`)
- add the ability to set the playlist creation mode: absolute links, relative links, or both (`Settings` - `Music` - `Create M3U8: creation mode`)
- Threads: **saved posts downloading**
- Feed
- hotkeys `Esc` and `Ctrl+W` to close the form
- the ability to search for missing files in *special feeds*
- Scheduler: the ability to execute a script after the scheduler plan is executed *(`Settings` - `Behavior`)*
- Main window:
- added hotkey `Ctrl+F` to show the feed
- changed the hotkey from `Ctrl+F` to `Alt+F` to show the search form
- Updated
- yt-dlp up to version **2024.07.16**
- Fixed
- YouTube (standalone app): video files with line breaks in the name do not download correctly
- OnlyFans: rules parsing bug
- Minor bugs
# 2024.6.25.0
*2024-06-25*
**ATTENTION! To support downloading of DRM protected videos (OnlyFans), please update OF-Scraper to version [3.10.7](https://github.com/datawhores/OF-Scraper/releases/tag/3.10.7) (download `zip`, not `exe`).**
- Added
- OnlyFans: **new dynamic rules updating algorithm**
- Feed: ability to set the last session as the current one
- Updated
- gallery-dl up to version **1.27.1**
- Fixed
- Minor bugs
# 2024.6.10.0 # 2024.6.10.0
*2024-06-10* *2024-06-10*

162
FAQ.md
View File

@@ -1,120 +1,98 @@
# Frequently asked questions
**Please read the [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) Before asking a question!** **Join our Discord server**: https://discord.gg/uFNUXvFFmg
<br/>*You can get help faster there!*
**Also read [here](README.md) for basic information.** # Docs
- Basic info: https://github.com/AAndyProgram/SCrawler/blob/main/README.md
- **GUIDE**: https://github.com/AAndyProgram/SCrawler/wiki/
- Settings: https://github.com/AAndyProgram/SCrawler/wiki/Settings
- Discord: https://discord.gg/uFNUXvFFmg
Most of your questions are already answered. All settings, functions, buttons and everything else described in the guide. Most of your questions are already answered. All settings, functions, buttons and everything else described in the guide.
Any other questions I will keep in this file. # Backup
I strongly recommend you to **regularly** create backup copies of the settings files. **An [example script](https://github.com/AAndyProgram/SCrawler/blob/main/Tools/ArchiveSCrawlerUsersDataFiles.bat) for this** on GitHub (you **should adapt** it to your environment, and you can use it when [SCrawler is closed](https://github.com/AAndyProgram/SCrawler/wiki/Settings#behavior)).
---- **This way you'll always have the latest backup of your settings files and can restore it if something goes wrong!**
#### Q: **HOW TO SETUP COOKIES** # How to report a problem
1. **Post your problem [here](https://github.com/AAndyProgram/SCrawler/issues) or in the [help channel](https://discord.com/channels/1124032649682493462/1124281838056259614) on our Discord server**
A: https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies 2. Attach the **profile URLs or links** that you cannot download.
3. Attach the **LOG** if it exists.
---- 4. Attach **the environment information** copied from SCrawler (click the top right info button in the main window, then the `Environment` button, then the `Copy` button, and paste the copied text into the message).
5. *Add screenshots to illustrate the problem (**optional**)*
#### Q: **Does this program have GUI or CLI.**
A: This is a GUI program.
----
#### Q: **Will CLI be added in the future?**
A: NO.
----
#### Q: **I want to add "...." site. How to request.**
<!---A: How to request a new site you can read [here](CONTRIBUTING.md#how-to-request-a-new-site)--->
**I'm currently not accepting requests to develop new sites.**
----
#### Q: **Site download failed.**
A: Check your credentials and **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**. If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
**You also can join our Discord server**: https://discord.gg/uFNUXvFFmg
<br/>*You can get help faster there!*
**ATTENTION! Issues without URLs will be closed without a response!** **ATTENTION! Issues without URLs will be closed without a response!**
---- # Most frequently questions about SCrawler
#### Q: **I have set credentials but still nothing is downloading** **If something doesn't download, always check the [SITE'S REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements) before asking questions!**
A: Click the `Start downloading` button or press `F5` *How to use: find your problem in the list and read the answer.*
---- ## General questions
- **PROFILES**
- I added a profile but **nothing downloaded** :arrow_forward: check your cookies and [site requirements](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements). If there are any optional fields that you don't fill in, do so. Still nothing works - [report it](#how-to-report-a-problem)!
- User downloading failed :arrow_forward: check your credentials and **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**. If all settings are set and nothing works, [report it](#how-to-report-a-problem). **Don't forget to attach the LOG.**
- [How to redownload user](https://github.com/AAndyProgram/SCrawler/wiki#redownload-user)
- How to **add profile** to download :arrow_forward: copy the **[profile URL](https://github.com/AAndyProgram/SCrawler/wiki#add-user)** and press `Insert` or `Ctrl+Insert`. **ALWAYS PASTE THE USER PROFILE URL**. After that select this user and press `F5` or click the `Download selected` button.
- How to download **[saved posts](https://github.com/AAndyProgram/SCrawler/wiki#saved-posts)**
- **[HOW TO ADD COOKIES](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies)**
- [How to report a problem](#how-to-report-a-problem)
- I want you to **add the site** to SCrawler :arrow_forward: **I'm not currently accepting requests to add new sites**, but you can [create a plugin](https://github.com/AAndyProgram/SCrawler/wiki/Plugins) (for your site) for SCrawler.
- What language is SCrawler written in :arrow_forward: `vb.net`
- I don't know `vb.net` and I can't write a plugin :arrow_forward: you can write a plugin in `C#`
- I have a suggestion, will it be added :arrow_forward: maybe if it interested me.
- How to name files using a pattern (e.g. `Site_PostID_Name.jpg`) :arrow_forward: **there is no such functionality and there are no such plans**.
- **DON'T CHANGE THE DEFAULT SITE SETTINGS UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!** SCrawler already has all the default settings to work. You only need to add credentials (where [required](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)).
- My computer shut down while SCrawler was running and now **SCrawler won't start or some users are missing** :arrow_forward: restore user settings from [backup](#backup).
- Installation, update and configuration
- How to install: https://github.com/AAndyProgram/SCrawler#installation
- How to update: https://github.com/AAndyProgram/SCrawler#updating
- What file executes the program: **`SCrawler.exe`**
- Where to find binaries: https://github.com/AAndyProgram/SCrawler/releases/latest
- [How to build from source](https://github.com/AAndyProgram/SCrawler/blob/main/CONTRIBUTING.md#how-to-build-from-source)
- [Video how to configure](#video-how-to-configure)
- **Antivirus**
- **Antivirus detects SCrawler as a virus** :arrow_forward: SCrawler doesn't contain any viruses at all. All code is posted on GitHub. You can review it. I have nothing to hide. SCrawler just downloads pictures and videos. That's all. If you trust SCrawler, you should just add it to the antivirus exceptions, as I did. Sometimes antiviruses identify SCawler as a virus. This is usually related to the number of files being edited (users' settings files) and the number of files being downloaded. In this case, the antivirus can also remove these files, which will damage users' settings. **If you don't trust SCrawler, just delete it.**
- **Antivirus detects gallery-dl as a virus** :arrow_forward: it's a trustworthy program that is trusted by thousands of people around the world. Antiviruses identify some builds as containing viruses, but this is not true. **If you don't trust gallery-dl, you can simply delete it**. **But if you delete it, you won't be able to download [Twitter & Pinterest](https://github.com/AAndyProgram/SCrawler/wiki/Settings#gallery-dl).** You should decide for yourself.
#### Q: **Where can I find the release?** ## Sites questions
A: https://github.com/AAndyProgram/SCrawler/releases/latest *How to use: find the site you need in the list and read the answer.*
---- - Reddit: don't use credentials at all or configure [OAuth](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-get-reddit-credentials). **Reddit profiles can be downloaded without any credentials at all. Subreddits require OAuth! If nothing downloads, use OAuth!** Don't use OAuth token to download saved posts (use cookies only).
- **META** (**Instagram**, Threads, Facebook): you need **cookies** and fill in **all fields**
- **Instagram saved posts**: I don't consider questions like "I have 10k saved posts and only 1000 were downloaded". Download posts, remove them from saved posts, delete the `Saved posts` **settings folder**, repeat.
- TikTok: works via yt-dlp. If something doesn't download, we need to wait until yt-dlp fixes it. TikTok doesn't require cookies to download.
- Porn sites: **COOKIES**!
- ThisVid: https://github.com/AAndyProgram/SCrawler/wiki/Settings#thisvid-faq
- **OnlyFans**: cookies + **all fields** + [OF-Scraper (download the correct version that I pointed)](https://github.com/AAndyProgram/SCrawler/wiki/Settings#of-scraper) & [mp4decrypt](https://www.bento4.com/downloads/) to download DRM protected videos. [OF-Scraper support](https://github.com/AAndyProgram/SCrawler/wiki/Settings#of-scraper-support). Also read [this](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans-faq)
- **JustForFans**: **THE VIDEO ISN'T DOWNLOADING AT THE MOMENT** ([Issue](https://discord.com/channels/1124032649682493462/1205547615199039551/1231349555132366870))
#### Q: **How to run the program?** ## Other questions
A: Double-click `SCrawler.exe` ### Does the program remember the last download and check for new posts, downloading only new posts, or does the program download the entire profile every time
The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**!
---- ### Does this program have a GUI or CLI, and will a CLI be added in the future
This is a GUI program and **NO**, <u>CLI will not be added</u>
#### Q: **Where to find binaries?** ### How to remove the label
There is no functionality to remove an individual label. You can open the `Labels.txt` file in the program settings folder and delete any label you want. You also can delete this file (`Labels.txt`). In this case, when SCrawler is launched, the list of labels will be populated only with existing labels (from the user data files).
A: https://github.com/AAndyProgram/SCrawler/releases/latest ### How to remove a user from the blacklist
Just add that user back to the program. In the dialog box that opens, click the `Add and remove from blacklist` button.
---- ### You lost me. Your program is too complicated.
**I'm fine with that**. If the program is too complicated for you or you can't configure it, I can only suggest you find another (easier) program. I really don't mind! The program is free. I develop SCrawler for myself and publish it on GitHub because people found my program useful. If someone can't use it or doesn't like it, I'm okay with it.
#### Q: **Does the program remember the last download and check for new posts, downloading only new posts? Or does the program download the entire profile every time?** ### Add a step-by-step guide or video on how to use the program
**NO!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I'll add it. All options and their purposes are described on the wiki. The wiki also contains a description of all the settings and how to configure them. For complex settings there is a step-by-step guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I've developed a program with an intuitive interface. There is a `Settings` button, download buttons, a context menu that appears when you right-click on a user, and other controls. Anyone can use it.
A: The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**! **There is already a [video](#video-how-to-configure) example of how to configure a site.**
---- # Video how to configure
#### Q: **How to redownload all data**
A: https://github.com/AAndyProgram/SCrawler/wiki#redownload-user
----
#### Q: **How to remove the label**
A: There is no functionality to remove an individual label. You can open the `Labels.txt` file in the program settings folder and delete any label you want. You also can delete this file (`Labels.txt`). In this case, when the program starts, the list of labels list will be updated with only existing labels (from the user data files).
----
#### Q: **How to remove a user from the blacklist**
A: Just add that user back to the program. In the dialog box that opens, click on the `Add and remove from blacklist` button.
----
#### Q: **Why don't you answer how it works**
A: Because **I don't want to**. I don't want to waste my time explaining things that are already covered in the **[GUIDE](https://github.com/AAndyProgram/SCrawler/wiki)**! If you didn't bother to read the guide, why would I waste my time?! ALL FUNCTIONALITY IS DESCRIBED IN THE GUIDE. Before publishing a new release, I update the guide. If you don't respect my work, I don't waste my time.
----
#### Q: **You lost me. Your program is too complicated.**
A: **I'm fine with that**. If the program is difficult for you or you can't configure it, I can only suggest you find another (easier) program. I really don't mind! The program is free. I am develop SCrawler for myself and publish on GitHub because people found my program useful. If someone can't use it or doesn't like it, I'm fine.
----
#### Q: **I can't configure something**
A: I can only [suggest](#q-you-lost-me-your-program-is-too-complicated) you find another (easier) program.
----
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
A: **NO!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.
**The following video was recorded by a user who loves SCrawler and demonstrates how to add credentials using Instagram as an example:** **The following video was recorded by a user who loves SCrawler and demonstrates how to add credentials using Instagram as an example:**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -33,16 +33,16 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
![YouTube application](ProgramScreenshots/AppYouTube.png) ![YouTube application](ProgramScreenshots/AppYouTube.png)
# What can program do: # What can program do:
- Download pictures and videos from users' profiles and subreddits: - Download pictures and videos from user profiles:
- YouTube videos, shorts, community feeds, users, artists, playlists, music, tracks; - YouTube videos, shorts, community feeds, users, artists, playlists, music, tracks;
- Reddit images, galleries of images, videos, saved posts; - Reddit images, galleries of images, videos, saved posts;
- Redgifs videos (https://www.redgifs.com/); - Redgifs images and videos (https://www.redgifs.com/);
- Twitter images and videos, saved (bookmarked) posts, likes, communities; - Twitter images and videos, saved (bookmarked) posts, likes, communities;
- OnlyFans images and videos, saved (bookmarked) posts, stories; - OnlyFans images and videos, saved (bookmarked) posts, stories;
- JustForFans images and videos, saved (bookmarked) posts; - JustForFans images and videos, saved (bookmarked) posts;
- Mastodon images and videos, saved (bookmarked) posts; - Mastodon images and videos, saved (bookmarked) posts;
- Instagram images and videos, tagged posts, stories, saved posts; - Instagram images and videos, tagged posts, stories, saved posts;
- Threads images and videos; - Threads images and videos, saved posts;
- Facebook images and videos, stories, saved posts; - Facebook images and videos, stories, saved posts;
- TikTok videos; - TikTok videos;
- Pinterest boards, users, saved posts; - Pinterest boards, users, saved posts;
@@ -57,7 +57,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- Download [saved posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts) - Download [saved posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
- Add users from parsed channel - Add users from parsed channel
- **Advanced user management** - **Advanced user management**
- **Automation** ([downloading data automatically](https://github.com/AAndyProgram/SCrawler/wiki/Settings#automation) every ```X``` minutes) - **Automation** ([downloading data automatically](https://github.com/AAndyProgram/SCrawler/wiki/Settings#automation) every `X` minutes)
- **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files and subscriptions posts) - **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files and subscriptions posts)
- Multiple accounts support - Multiple accounts support
- Labeling users - Labeling users
@@ -82,12 +82,12 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- **Instagram** - **Instagram**
- **Threads** - **Threads**
- **Facebook** - **Facebook**
- JustForFans *(partial support)*[^1] - JustForFans *(partial support) ([video issue](https://discord.com/channels/1124032649682493462/1205547615199039551/1231349555132366870))*[^1]
- Mastodon *(out of support)* - Mastodon *(out of support)*
- TikTok - TikTok
- RedGifs - RedGifs
- Pinterest - Pinterest
- Imgur - Imgur *(out of support)*
- Gfycat - Gfycat
- LPSG - LPSG
- **PornHub** - **PornHub**
@@ -109,7 +109,7 @@ First, the program downloads the full profile. After the program downloads only
# Requirements # Requirements
- Windows 10, 11 with NET Framework 4.6.1 or higher (v4.6.1 must be installed). You can check version compatibility with this [tool](Tools/NET.FrameworkVersion.ps1). - **Windows 10, 11** with NET Framework 4.6.1 or higher (v4.6.1 must be installed). You can check version compatibility with this [tool](Tools/NET.FrameworkVersion.ps1).
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)** - **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
# Guide # Guide
@@ -157,7 +157,7 @@ First, the program downloads the full profile. After the program downloads only
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush: **Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush:
**Don't put program in the ```Program Files``` system folder (this is portable program and program settings are stored in the program folder)** **Don't put program in the `Program Files` system folder (this is portable program and program settings are stored in the program folder)**
**I highly doubt you can run SCrawler on Linux or Mac. SCrawler is a program that is heavily dependent on Windows.** **I highly doubt you can run SCrawler on Linux or Mac. SCrawler is a program that is heavily dependent on Windows.**
@@ -183,7 +183,7 @@ The program has an intuitive interface.
[![How to configure](https://img.youtube.com/vi/XDn7zG4I700/0.jpg)](https://www.youtube.com/watch?v=XDn7zG4I700) [![How to configure](https://img.youtube.com/vi/XDn7zG4I700/0.jpg)](https://www.youtube.com/watch?v=XDn7zG4I700)
Just add a user profile and **click the ```Download``` button**. Just add a user profile and **click the `Download` button**.
```mermaid ```mermaid
stateDiagram stateDiagram

View File

@@ -84,6 +84,11 @@ Namespace API.YouTube.Base
Before = 1 Before = 1
After = 2 After = 2
End Enum End Enum
Public Enum M3U8CreationMode As Integer
Relative = 0
Absolute = 1
Both = 2
End Enum
Public Structure MediaObject : Implements IIndexable, IComparable(Of MediaObject) Public Structure MediaObject : Implements IIndexable, IComparable(Of MediaObject)
Public Type As Plugin.UserMediaTypes Public Type As Plugin.UserMediaTypes
Public ID As String Public ID As String

View File

@@ -131,22 +131,28 @@ Namespace API.YouTube.Base
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program"), DefaultValue(False)> <Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program"), DefaultValue(False)>
Private Property IDownloaderSettings_OpenFolderInOtherProgram As Boolean Implements IDownloaderSettings.OpenFolderInOtherProgram Private Property IDownloaderSettings_OpenFolderInOtherProgram As Boolean Implements IDownloaderSettings.OpenFolderInOtherProgram
Get Get
Return OpenFolderInOtherProgram.Use Return OpenFolderInOtherProgram.Attribute.ValueTemp
End Get End Get
Set(ByVal use As Boolean) Set(ByVal use As Boolean)
OpenFolderInOtherProgram.Use = use OpenFolderInOtherProgram.Attribute.ValueTemp = use
End Set End Set
End Property End Property
Private Function ShouldSerializeIDownloaderSettings_OpenFolderInOtherProgram() As Boolean
Return DirectCast(OpenFolderInOtherProgram.Attribute, IGridValue).ShouldSerializeValue
End Function
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program (command)"), <Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program (command)"),
Description("The command to open a folder."), DefaultValue("")> Description("The command to open a folder."), DefaultValue("")>
Private Property IDownloaderSettings_OpenFolderInOtherProgram_Command As String Implements IDownloaderSettings.OpenFolderInOtherProgram_Command Private Property IDownloaderSettings_OpenFolderInOtherProgram_Command As String Implements IDownloaderSettings.OpenFolderInOtherProgram_Command
Get Get
Return OpenFolderInOtherProgram Return OpenFolderInOtherProgram.ValueTemp
End Get End Get
Set(ByVal command As String) Set(ByVal command As String)
OpenFolderInOtherProgram.Value = command OpenFolderInOtherProgram.ValueTemp = command
End Set End Set
End Property End Property
Private Function ShouldSerializeIDownloaderSettings_OpenFolderInOtherProgram_Command() As Boolean
Return DirectCast(OpenFolderInOtherProgram, IGridValue).ShouldSerializeValue
End Function
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Check new version at start")> <Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Check new version at start")>
Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean) Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean)
#End Region #End Region
@@ -305,6 +311,12 @@ Namespace API.YouTube.Base
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 1080), Category("Defaults Video"), DisplayName("Default definition"), <Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 1080), Category("Defaults Video"), DisplayName("Default definition"),
Description("The default maximum video resolution. -1 for max definition")> Description("The default maximum video resolution. -1 for max definition")>
Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer) Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer)
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, True), Category("Defaults Video"), DisplayName("Allow webm formats"),
Description("Allow webm formats over http if mp4 formats are not available. Default: true.")>
Public ReadOnly Property DefaultVideoAllowWebm As XMLValue(Of Boolean)
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}), Category("Defaults Video"), DisplayName("Convert non-AVC codecs to AVC"),
Description("Convert non-AVC codecs (eg 'VP9') to AVC. Not recommended due to high CPU usage!")>
Public ReadOnly Property DefaultVideoConvertNonAVC As XMLValue(Of Boolean)
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, False), Category("Defaults Video"), DisplayName("Embed thumbnail (video)"), <Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, False), Category("Defaults Video"), DisplayName("Embed thumbnail (video)"),
Description("Embed thumbnail in the video as cover art. Default: true.")> Description("Embed thumbnail in the video as cover art. Default: true.")>
Public ReadOnly Property DefaultVideoEmbedThumbnail As XMLValue(Of Boolean) Public ReadOnly Property DefaultVideoEmbedThumbnail As XMLValue(Of Boolean)
@@ -407,6 +419,9 @@ Namespace API.YouTube.Base
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail"), <Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail"),
Description("Embed thumbnail in the audio as cover art. Default: true.")> Description("Embed thumbnail in the audio as cover art. Default: true.")>
Public ReadOnly Property DefaultAudioEmbedThumbnail As XMLValue(Of Boolean) Public ReadOnly Property DefaultAudioEmbedThumbnail As XMLValue(Of Boolean)
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail (cover)"),
Description("Try embedding the playlist cover (if it exists) as cover art. Default: true.")>
Public ReadOnly Property DefaultAudioEmbedThumbnail_Cover As XMLValue(Of Boolean)
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail (extracted files)"), <Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, True), Category("Defaults Audio"), DisplayName("Embed thumbnail (extracted files)"),
Description("Embed thumbnail in the extracted (additional file ('mp3' only)) audio as cover art. Default: true.")> Description("Embed thumbnail in the extracted (additional file ('mp3' only)) audio as cover art. Default: true.")>
Public ReadOnly Property DefaultAudioEmbedThumbnail_ExtractedFiles As XMLValue(Of Boolean) Public ReadOnly Property DefaultAudioEmbedThumbnail_ExtractedFiles As XMLValue(Of Boolean)
@@ -432,6 +447,9 @@ Namespace API.YouTube.Base
<Browsable(True), GridVisible, XMLVN({"Playlists"}), Category("Music"), DisplayName("M3U8 Append file number"), <Browsable(True), GridVisible, XMLVN({"Playlists"}), Category("Music"), DisplayName("M3U8 Append file number"),
Description("Add file number to file name. Default: false.")> Description("Add file number to file name. Default: false.")>
Public ReadOnly Property MusicPlaylistCreate_M3U8_AppendNumber As XMLValue(Of Boolean) Public ReadOnly Property MusicPlaylistCreate_M3U8_AppendNumber As XMLValue(Of Boolean)
<Browsable(True), GridVisible, XMLVN({"Playlists"}, M3U8CreationMode.Relative), Category("Music"), DisplayName("Create M3U8: creation mode"),
Description("Set the playlist creation mode: absolute links, relative links, or both. If 'Both' is selected, two playlists will be created. Default: 'Relative'.")>
Public ReadOnly Property MusicPlaylistCreate_CreationMode As XMLValue(Of M3U8CreationMode)
#End Region #End Region
#End Region #End Region
#Region "Defaults Subtitles" #Region "Defaults Subtitles"

View File

@@ -32,6 +32,7 @@ Namespace API.YouTube.Controls
Private Initialization As Boolean = True Private Initialization As Boolean = True
Private ReadOnly InheritsFromContainer As Boolean Private ReadOnly InheritsFromContainer As Boolean
Private ReadOnly M3U8Files As List(Of SFile) Private ReadOnly M3U8Files As List(Of SFile)
Friend Property UseCookies As Boolean = False
Private ReadOnly Property M3U8FilesFull As List(Of SFile) Private ReadOnly Property M3U8FilesFull As List(Of SFile)
Get Get
Return ListAddList(Nothing, M3U8Files, LAP.NotContainsOnly).ListAddValue(CMB_PLS.Text, LAP.NotContainsOnly) Return ListAddList(Nothing, M3U8Files, LAP.NotContainsOnly).ListAddValue(CMB_PLS.Text, LAP.NotContainsOnly)
@@ -65,6 +66,7 @@ Namespace API.YouTube.Controls
CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS) CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS)
Me.InheritsFromContainer = InheritsFromContainer Me.InheritsFromContainer = InheritsFromContainer
MyFieldsChecker = New FieldsChecker MyFieldsChecker = New FieldsChecker
UseCookies = MyYouTubeSettings.DefaultUseCookies
End Sub End Sub
#End Region #End Region
#Region "Form handlers" #Region "Form handlers"
@@ -227,7 +229,7 @@ Namespace API.YouTube.Controls
Dim data As IEnumerable(Of Control) Dim data As IEnumerable(Of Control)
If .HasElements Then If .HasElements Then
data = .Elements.Select(Function(ee) New MediaItem(ee, True) With {.Dock = DockStyle.Fill, .Checked = ee.Checked}) data = .Elements.Select(Function(ee) New MediaItem(ee, True) With {.Dock = DockStyle.Fill, .Checked = ee.Checked, .UseCookies = UseCookies})
Else Else
data = (From m As MediaObject In .Self.MediaObjects data = (From m As MediaObject In .Self.MediaObjects
Where m.Type = __contentType Where m.Type = __contentType

View File

@@ -59,6 +59,7 @@ Namespace API.YouTube
Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue) Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue)
Friend ReadOnly MusicUrlApply As RParams = RParams.DMS("https://([w\.]*)youtube.com.+", 1, RegexReturn.Replace, EDP.ReturnValue, Friend ReadOnly MusicUrlApply As RParams = RParams.DMS("https://([w\.]*)youtube.com.+", 1, RegexReturn.Replace, EDP.ReturnValue,
CType(Function(input$) "music.", Func(Of String, String)), String.Empty) CType(Function(input$) "music.", Func(Of String, String)), String.Empty)
Friend ReadOnly M3U8ExcludedSymbols As String() = {".", ",", ":", "/", "\", "(", ")", "[", "]"}
<Extension> Friend Function ToMusicUrl(ByVal URL As String, ByVal IsMusic As Boolean) As String <Extension> Friend Function ToMusicUrl(ByVal URL As String, ByVal IsMusic As Boolean) As String
Try : Return If(IsMusic And Not URL.IsEmptyString, CStr(RegexReplace(URL, MusicUrlApply)).IfNullOrEmpty(URL), URL) : Catch : Return URL : End Try Try : Return If(IsMusic And Not URL.IsEmptyString, CStr(RegexReplace(URL, MusicUrlApply)).IfNullOrEmpty(URL), URL) : Catch : Return URL : End Try
End Function End Function
@@ -66,6 +67,7 @@ Namespace API.YouTube
If Not f.IsEmptyString And Not f.Name.IsEmptyString Then If Not f.IsEmptyString And Not f.Name.IsEmptyString Then
Dim ff As SFile = f Dim ff As SFile = f
ff.Name = ff.Name.StringRemoveWinForbiddenSymbols.StringTrim ff.Name = ff.Name.StringRemoveWinForbiddenSymbols.StringTrim
ff.Name = ff.Name.StringReplaceSymbols({vbLf, vbCr, vbCrLf}, String.Empty, EDP.ReturnValue)
ff.Name = ff.Name.StringTrimEnd(".") ff.Name = ff.Name.StringTrimEnd(".")
If Not ff.Name.IsEmptyString And Not MyYouTubeSettings.FileRemoveCharacters.IsEmptyString Then _ If Not ff.Name.IsEmptyString And Not MyYouTubeSettings.FileRemoveCharacters.IsEmptyString Then _
ff.Name = ff.Name.StringReplaceSymbols(MyYouTubeSettings.FileRemoveCharacters.Value.AsList.ListCast(Of String).ToArray, String.Empty, EDP.ReturnValue) ff.Name = ff.Name.StringReplaceSymbols(MyYouTubeSettings.FileRemoveCharacters.Value.AsList.ListCast(Of String).ToArray, String.Empty, EDP.ReturnValue)

View File

@@ -437,7 +437,7 @@ Namespace DownloadObjects.STDownloader
Else Else
RaiseEvent BeforeOpenEditor(Me, MyContainer) RaiseEvent BeforeOpenEditor(Me, MyContainer)
End If End If
Using f As New VideoOptionsForm(MyContainer, initProtected Or isFull) Using f As New VideoOptionsForm(MyContainer, initProtected Or isFull) With {.UseCookies = UseCookies}
f.ShowDialog() f.ShowDialog()
.Protected = IIf(f.DialogResult = DialogResult.OK, True, initProtected) .Protected = IIf(f.DialogResult = DialogResult.OK, True, initProtected)
End Using End Using
@@ -465,12 +465,12 @@ Namespace DownloadObjects.STDownloader
If Not MyContainer Is Nothing Then If Not MyContainer Is Nothing Then
Dim f As Form = Nothing Dim f As Form = Nothing
Select Case MyContainer.ObjectType Select Case MyContainer.ObjectType
Case Base.YouTubeMediaType.Single : f = New VideoOptionsForm(MyContainer, True) Case Base.YouTubeMediaType.Single : f = New VideoOptionsForm(MyContainer, True) With {.UseCookies = UseCookies}
Case Base.YouTubeMediaType.Channel, Base.YouTubeMediaType.PlayList Case Base.YouTubeMediaType.Channel, Base.YouTubeMediaType.PlayList
If MyContainer.IsMusic Then If MyContainer.IsMusic Then
f = New MusicPlaylistsForm(MyContainer) f = New MusicPlaylistsForm(MyContainer)
Else Else
f = New VideoOptionsForm(MyContainer, True) f = New VideoOptionsForm(MyContainer, True) With {.UseCookies = UseCookies}
End If End If
End Select End Select
If Not f Is Nothing Then If Not f Is Nothing Then

View File

@@ -132,7 +132,8 @@ Namespace DownloadObjects.STDownloader
#End Region #End Region
#Region "Controls" #Region "Controls"
Protected Sub ControlCreateAndAdd(ByVal Container As IYouTubeMediaContainer, Optional ByVal DisableDownload As Boolean = False, Protected Sub ControlCreateAndAdd(ByVal Container As IYouTubeMediaContainer, Optional ByVal DisableDownload As Boolean = False,
Optional ByVal PerformClick As Boolean = True, Optional ByVal IsLoading As Boolean = False) Optional ByVal PerformClick As Boolean = True, Optional ByVal IsLoading As Boolean = False,
Optional ByVal UseCookies As Boolean = False)
ControlInvokeFast(TP_CONTROLS, Sub() ControlInvokeFast(TP_CONTROLS, Sub()
With TP_CONTROLS With TP_CONTROLS
.SuspendLayout() .SuspendLayout()
@@ -142,7 +143,7 @@ Namespace DownloadObjects.STDownloader
.RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 60)) .RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 60))
.RowCount = .RowStyles.Count .RowCount = .RowStyles.Count
OffsetControls(0, True) OffsetControls(0, True)
Dim cnt As New MediaItem(Container) With {.Dock = DockStyle.Fill, .Margin = New Padding(0)} Dim cnt As New MediaItem(Container) With {.Dock = DockStyle.Fill, .Margin = New Padding(0), .UseCookies = UseCookies}
AddHandler cnt.FileDownloaded, AddressOf MediaControl_FileDownloaded AddHandler cnt.FileDownloaded, AddressOf MediaControl_FileDownloaded
AddHandler cnt.Removal, AddressOf MediaControl_Removal AddHandler cnt.Removal, AddressOf MediaControl_Removal
AddHandler cnt.DownloadAgain, AddressOf MediaControl_DownloadAgain AddHandler cnt.DownloadAgain, AddressOf MediaControl_DownloadAgain
@@ -333,19 +334,19 @@ Namespace DownloadObjects.STDownloader
If Not c Is Nothing Then If Not c Is Nothing Then
Dim f As Form Dim f As Form
Select Case c.ObjectType Select Case c.ObjectType
Case YouTubeMediaType.Single : f = New VideoOptionsForm(c) Case YouTubeMediaType.Single : f = New VideoOptionsForm(c) With {.UseCookies = useCookies}
Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList
If c.IsMusic Then If c.IsMusic Then
f = New MusicPlaylistsForm(c) f = New MusicPlaylistsForm(c)
Else Else
f = New VideoOptionsForm(c) f = New VideoOptionsForm(c) With {.UseCookies = useCookies}
End If End If
Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType") Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType")
End Select End Select
If Not f Is Nothing Then If Not f Is Nothing Then
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
f.ShowDialog() f.ShowDialog()
If f.DialogResult = DialogResult.OK AndAlso ValidateContainerURL(c) Then ControlCreateAndAdd(c, disableDown) If f.DialogResult = DialogResult.OK AndAlso ValidateContainerURL(c) Then ControlCreateAndAdd(c, disableDown,,, useCookies)
f.Dispose() f.Dispose()
End If End If
End If End If

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below: ' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2024.6.10.0")> <Assembly: AssemblyVersion("2024.10.24.0")>
<Assembly: AssemblyFileVersion("2024.6.10.0")> <Assembly: AssemblyFileVersion("2024.10.24.0")>
<Assembly: NeutralResourcesLanguage("en")> <Assembly: NeutralResourcesLanguage("en")>

View File

@@ -175,7 +175,9 @@ Namespace API.YouTube.Objects
Protected _ThumbnailUrl As String = String.Empty Protected _ThumbnailUrl As String = String.Empty
<XMLEC> Public Overridable Property ThumbnailUrl As String Implements IDownloadableMedia.ThumbnailUrl <XMLEC> Public Overridable Property ThumbnailUrl As String Implements IDownloadableMedia.ThumbnailUrl
Get Get
If _ThumbnailUrl.IsEmptyString And Thumbnails.Count > 0 Then If Not CoverURL.IsEmptyString Then
Return CoverURL
ElseIf _ThumbnailUrl.IsEmptyString And Thumbnails.Count > 0 Then
Return Thumbnails.FirstOrDefault.URL Return Thumbnails.FirstOrDefault.URL
Else Else
Return _ThumbnailUrl Return _ThumbnailUrl
@@ -899,10 +901,14 @@ Namespace API.YouTube.Objects
Return Nothing Return Nothing
End Try End Try
End Function End Function
Private Function GetPlaylistRow(ByVal Element As YouTubeMediaContainerBase, Optional ByVal __file As SFile = Nothing) As String Private Function GetPlaylistRow(ByVal Element As YouTubeMediaContainerBase, Optional ByVal __file As SFile = Nothing,
Optional ByVal Mode As M3U8CreationMode = M3U8CreationMode.Absolute) As String
Const m3u8DataRow$ = "#EXTINF:{0},{1}" & vbCrLf & "{2}" Const m3u8DataRow$ = "#EXTINF:{0},{1}" & vbCrLf & "{2}"
With Element With Element
Dim f As SFile = __file.IfNullOrEmpty(.File) Dim f As SFile = __file.IfNullOrEmpty(.File)
Dim fStr$ = f.ToString.StringReplaceSymbols({"\"}, "/", EDP.ReturnValue)
Dim __f$ = SymbolsConverter.ASCII.Extended.EncodeSymbolsOnly(If(Mode = M3U8CreationMode.Absolute, fStr, f.File), M3U8ExcludedSymbols)
If Mode = M3U8CreationMode.Absolute Then __f = $"file:///{__f}"
Dim fName$ = .Title.IfNullOrEmpty(f.Name) Dim fName$ = .Title.IfNullOrEmpty(f.Name)
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendNumber And .PlaylistIndex > 0 Then fName = $"{ .PlaylistIndex}. {fName}" If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendNumber And .PlaylistIndex > 0 Then fName = $"{ .PlaylistIndex}. {fName}"
If Not .UserTitle.IsEmptyString Then If Not .UserTitle.IsEmptyString Then
@@ -910,10 +916,7 @@ Namespace API.YouTube.Objects
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendArtist Then fName = $"{ .UserTitle} - {fName}" If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendArtist Then fName = $"{ .UserTitle} - {fName}"
End If End If
If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendExt Then fName &= $".{f.Extension}" If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendExt Then fName &= $".{f.Extension}"
Return String.Format(m3u8DataRow, Return String.Format(m3u8DataRow, CInt(.Duration.TotalSeconds), fName, __f)
CInt(.Duration.TotalSeconds),
fName,
$"file:///{SymbolsConverter.ASCII.EncodeSymbolsOnly(f)}")
End With End With
End Function End Function
Private ReadOnly DownloadProgressPattern As RParams = RParams.DMS("\[download\]\s*([\d\.,]+)", 1, EDP.ReturnValue) Private ReadOnly DownloadProgressPattern As RParams = RParams.DMS("\[download\]\s*([\d\.,]+)", 1, EDP.ReturnValue)
@@ -954,23 +957,41 @@ Namespace API.YouTube.Objects
Dim t As TextSaver = Nothing Dim t As TextSaver = Nothing
Try Try
Dim f As SFile Dim f As SFile
If MyYouTubeSettings.MusicPlaylistCreate_M3U8 Then Dim arr As M3U8CreationMode() = If(MyYouTubeSettings.MusicPlaylistCreate_CreationMode.Value = M3U8CreationMode.Both,
t = New TextSaver {M3U8CreationMode.Relative, M3U8CreationMode.Absolute},
t.AppendLine("#EXTM3U") {MyYouTubeSettings.MusicPlaylistCreate_CreationMode.Value})
Elements.ForEach(Sub(e) t.AppendLine(GetPlaylistRow(e))) Dim postfix$
f = $"{Elements(0).File.PathWithSeparator}Playlist.m3u8" Dim added As Boolean
t.SaveAs(f, EDP.SendToLog) Dim checkFile As Func(Of IYouTubeMediaContainer, Boolean) = Function(ByVal e As IYouTubeMediaContainer) As Boolean
If f.Exists Then AddFile(f) If e.File.Exists Then
t.Dispose() added = True
End If Return True
If MyYouTubeSettings.MusicPlaylistCreate_M3U Then Else
t = New TextSaver Return False
Elements.ForEach(Sub(e) t.AppendLine(e.File)) End If
f = $"{Elements(0).File.PathWithSeparator}Playlist.m3u" End Function
t.SaveAs(f, EDP.SendToLog) For Each cm As M3U8CreationMode In arr
If f.Exists Then AddFile(f) If arr.Length > 1 AndAlso cm = M3U8CreationMode.Absolute Then postfix = "Abs" Else postfix = String.Empty
t.Dispose() added = False
End If If MyYouTubeSettings.MusicPlaylistCreate_M3U8 Then
t = New TextSaver
t.AppendLine("#EXTM3U")
Elements.ForEach(Sub(e) If checkFile(e) Then t.AppendLine(GetPlaylistRow(e,, cm)))
f = $"{Elements(0).File.PathWithSeparator}Playlist{postfix}.m3u8"
If added Then t.SaveAs(f, EDP.SendToLog)
If f.Exists Then AddFile(f)
t.Dispose()
End If
added = False
If MyYouTubeSettings.MusicPlaylistCreate_M3U Then
t = New TextSaver
Elements.ForEach(Sub(e) If checkFile(e) Then t.AppendLine(If(cm = M3U8CreationMode.Relative, e.File.File, e.File.ToString)))
f = $"{Elements(0).File.PathWithSeparator}Playlist{postfix}.m3u"
If added Then t.SaveAs(f, EDP.SendToLog)
If f.Exists Then AddFile(f)
t.Dispose()
End If
Next
Catch ex As Exception Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[YouTubeMediaContainerBase.Download.CreatePlaylist]") ErrorsDescriber.Execute(EDP.SendToLog, ex, "[YouTubeMediaContainerBase.Download.CreatePlaylist]")
End Try End Try
@@ -1004,12 +1025,19 @@ Namespace API.YouTube.Objects
End If End If
Dim cDown As Boolean = False Dim cDown As Boolean = False
Dim fCover As SFile = Nothing
Dim cUrl$ = String.Empty
For Each elem In Elements For Each elem In Elements
With DirectCast(elem, YouTubeMediaContainerBase) With DirectCast(elem, YouTubeMediaContainerBase)
If Not .CoverDownloaded Then .CoverDownloaded = cDown 'If Not .CoverDownloaded Then .CoverDownloaded = cDown
.CoverDownloaded = cDown
.CoverFile = fCover
.CoverURL = cUrl
AddHandler .FileDownloadStarted, fDown AddHandler .FileDownloadStarted, fDown
.Download(UseCookies, Token) .Download(UseCookies, Token)
cDown = .CoverDownloaded cDown = .CoverDownloaded
fCover = .CoverFile
cUrl = .CoverURL
RemoveHandler .FileDownloadStarted, fDown RemoveHandler .FileDownloadStarted, fDown
End With End With
If Token.IsCancellationRequested Or disposedValue Then Exit For If Token.IsCancellationRequested Or disposedValue Then Exit For
@@ -1036,6 +1064,8 @@ Namespace API.YouTube.Objects
End Try End Try
End Sub End Sub
Protected CoverDownloaded As Boolean = False Protected CoverDownloaded As Boolean = False
Protected CoverFile As SFile = Nothing
Protected CoverURL As String = String.Empty
Private Sub DownloadPlaylistCover(ByVal PlsId As String, ByVal f As SFile, ByVal UseCookies As Boolean) Private Sub DownloadPlaylistCover(ByVal PlsId As String, ByVal f As SFile, ByVal UseCookies As Boolean)
Try Try
Dim url$ = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={PlsId}" Dim url$ = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={PlsId}"
@@ -1071,7 +1101,8 @@ Namespace API.YouTube.Objects
url = LinkFormatterSecure(u) url = LinkFormatterSecure(u)
f.Name = "cover" f.Name = "cover"
f.Extension = "jpg" f.Extension = "jpg"
If resp.DownloadFile(url, f, EDP.ReturnValue) And f.Exists Then CoverDownloaded = True : AddFile(f) If resp.DownloadFile(url, f, EDP.ReturnValue) And f.Exists Then _
CoverFile = f : CoverURL = url : CoverDownloaded = True : AddFile(f)
End If End If
End If End If
End Using End Using
@@ -1194,7 +1225,7 @@ Namespace API.YouTube.Objects
End With End With
If PlaylistCount > 0 And Not CoverDownloaded And Not PlaylistID.IsEmptyString Then DownloadPlaylistCover(PlaylistID, File, UseCookies) If PlaylistCount > 0 And Not CoverDownloaded And Not PlaylistID.IsEmptyString Then DownloadPlaylistCover(PlaylistID, File, UseCookies)
If prExists Then Progress.InformationTemporary = $"Download {MediaType}: post processing" If prExists Then Progress.InformationTemporary = "Downloading: post processing"
_ThumbnailFile = File _ThumbnailFile = File
_ThumbnailFile.Name &= "_thumb" _ThumbnailFile.Name &= "_thumb"
_ThumbnailFile.Extension = "jpg" _ThumbnailFile.Extension = "jpg"
@@ -1252,10 +1283,10 @@ Namespace API.YouTube.Objects
End Sub End Sub
Dim embedThumbTo As Action(Of SFile) = Dim embedThumbTo As Action(Of SFile) =
Sub(ByVal dFile As SFile) Sub(ByVal dFile As SFile)
If dFile.Exists And ThumbnailFile.Exists Then If dFile.Exists And CoverFile.IfNullOrEmpty(ThumbnailFile).Exists Then
Dim dFileNew As SFile = dFile Dim dFileNew As SFile = dFile
dFileNew.Name &= "_NEW" dFileNew.Name &= "_NEW"
.Execute($"ffmpeg -i ""{dFile}"" -i ""{ThumbnailFile}"" -map 0:0 -map 1:0 -c copy -id3v2_version 3 -metadata:s:v title=""Cover"" -metadata:s:v comment=""Cover"" ""{dFileNew}""") .Execute($"ffmpeg -i ""{dFile}"" -i ""{CoverFile.IfNullOrEmpty(ThumbnailFile)}"" -map 0:0 -map 1:0 -c copy -id3v2_version 3 -metadata:s:v title=""Cover"" -metadata:s:v comment=""Cover"" ""{dFileNew}""")
If dFileNew.Exists AndAlso dFile.Delete(,, EDP.ReturnValue) Then SFile.Rename(dFileNew, dFile) If dFileNew.Exists AndAlso dFile.Delete(,, EDP.ReturnValue) Then SFile.Rename(dFileNew, dFile)
End If End If
End Sub End Sub
@@ -1335,6 +1366,10 @@ Namespace API.YouTube.Objects
End If End If
End If End If
'mp3
If IsMusic And ObjectType = YouTubeMediaType.Single And File.Extension = mp3 And
Not mp3ThumbEmbedded And CoverFile.Exists And MyYouTubeSettings.DefaultAudioEmbedThumbnail_Cover Then embedThumbTo.Invoke(File)
'Update video 'Update video
ThrowAny(Token) ThrowAny(Token)
If SelectedVideoIndex >= 0 AndAlso tempFilesList.Count > 0 AndAlso tempFilesList.Exists(Function(tf) tf.ToReplace) Then If SelectedVideoIndex >= 0 AndAlso tempFilesList.Count > 0 AndAlso tempFilesList.Exists(Function(tf) tf.ToReplace) Then
@@ -1354,15 +1389,29 @@ Namespace API.YouTube.Objects
'Delete unrequsted files 'Delete unrequsted files
If tempFilesList.Count > 0 Then tempFilesList.ForEach(Sub(tfr) If Not tfr.Requested Then tfr.File.Delete(,, EDP.None)) : tempFilesList.Clear() If tempFilesList.Count > 0 Then tempFilesList.ForEach(Sub(tfr) If Not tfr.Requested Then tfr.File.Delete(,, EDP.None)) : tempFilesList.Clear()
'Update video FPS If SelectedVideoIndex >= 0 Then
If SelectedVideoIndex >= 0 AndAlso OutputVideoFPS > 0 AndAlso SelectedVideo.Bitrate <> OutputVideoFPS Then Dim reencodeFile As Action(Of String) =
f = File Sub(ByVal ffmpegCommand As String)
f.Name &= "tmp00" f = File
.Execute($"ffmpeg -i ""{File}"" -filter:v fps={OutputVideoFPS.ToString.Replace(",", ".")} -c:a copy ""{f}""") f.Name &= "tmp00"
If f.Exists Then .Execute(String.Format(ffmpegCommand, File.ToString, f.ToString))
File.Delete() If f.Exists Then
SFile.Rename(f, File,, EDP.LogMessageValue) If f.Size > 0 Then
End If File.Delete()
SFile.Rename(f, File,, EDP.LogMessageValue)
Else
f.Delete(, SFODelete.DeletePermanently, EDP.None)
End If
End If
End Sub
'Change video codec to AVC
If MyYouTubeSettings.DefaultVideoConvertNonAVC.Value AndAlso
Not SelectedVideo.Codec.IsEmptyString AndAlso Not SelectedVideo.Codec.Trim.ToLower.StartsWith("avc") Then _
reencodeFile("ffmpeg -i ""{0}"" -c:a copy -c:v libx264 ""{1}""")
'Update video FPS
If OutputVideoFPS > 0 AndAlso SelectedVideo.Bitrate <> OutputVideoFPS Then _
reencodeFile("ffmpeg -i ""{0}"" -filter:v fps=" & OutputVideoFPS.ToString.Replace(", ", ".") & " -c:a copy ""{1}""")
End If End If
End If End If
End If End If
@@ -1693,6 +1742,7 @@ Namespace API.YouTube.Objects
Dim obj As MediaObject Dim obj As MediaObject
Dim nValue# Dim nValue#
Dim sValue$ Dim sValue$
Dim allowWebm As Boolean = MyYouTubeSettings.DefaultVideoAllowWebm
Dim validCodecValue As Func(Of String, Boolean) = Function(codec) Not codec.IsEmptyString AndAlso Not codec = "none" Dim validCodecValue As Func(Of String, Boolean) = Function(codec) Not codec.IsEmptyString AndAlso Not codec = "none"
For Each ee In e({"formats"}) For Each ee In e({"formats"})
@@ -1743,12 +1793,13 @@ Namespace API.YouTube.Objects
Dim d As MediaObject = Nothing Dim d As MediaObject = Nothing
Dim expWebm As Predicate(Of MediaObject) = Function(mo) mo.Extension = webm Dim expWebm As Predicate(Of MediaObject) = Function(mo) mo.Extension = webm
Dim expAVC As Predicate(Of MediaObject) = Function(mo) mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc) Dim expAVC As Predicate(Of MediaObject) = Function(mo) mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean) = Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean, Boolean) =
Function(mo, exp, isTrue) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width Function(mo, exp, isTrue, checkHttp) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width And
Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False) (Not checkHttp OrElse mo.ProtocolType = Protocols.https)
Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True) Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False, allowWebm)
Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True) Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True, allowWebm)
Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False) Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True, False)
Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False, False)
For Each d In data For Each d In data
If MediaObjects.Count = 0 Then Exit For If MediaObjects.Count = 0 Then Exit For
If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm) If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm)

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below: ' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2024.6.10.0")> <Assembly: AssemblyVersion("2024.10.24.0")>
<Assembly: AssemblyFileVersion("2024.6.10.0")> <Assembly: AssemblyFileVersion("2024.10.24.0")>
<Assembly: NeutralResourcesLanguage("en")> <Assembly: NeutralResourcesLanguage("en")>

View File

@@ -28,6 +28,8 @@ Namespace API.Base
Friend Const GifsDownloadCaption As String = "Download GIFs" Friend Const GifsDownloadCaption As String = "Download GIFs"
Friend Const UseMD5ComparisonCaption As String = "Use MD5 comparison" Friend Const UseMD5ComparisonCaption As String = "Use MD5 comparison"
Friend Const UseMD5ComparisonToolTip As String = "Each image will be checked for existence using MD5" Friend Const UseMD5ComparisonToolTip As String = "Each image will be checked for existence using MD5"
Friend Const UserNameChangeCaption As String = "UserName"
Friend Const UserNameChangeToolTip As String = "If the user has changed their UserName, you can set a new name here. Not required for new users."
Private Sub New() Private Sub New()
End Sub End Sub
End Class End Class

View File

@@ -80,6 +80,8 @@ Namespace API.Base
Private _CollectionButtonsExists As Boolean = False Private _CollectionButtonsExists As Boolean = False
Private _CollectionButtonsColorsSet As Boolean = False Private _CollectionButtonsColorsSet As Boolean = False
Friend WithEvents BTT_CONTEXT_DOWN As ToolStripKeyMenuItem Friend WithEvents BTT_CONTEXT_DOWN As ToolStripKeyMenuItem
Friend WithEvents BTT_CONTEXT_DOWN_LIMIT As ToolStripKeyMenuItem
Friend WithEvents BTT_CONTEXT_DOWN_DATE As ToolStripKeyMenuItem
Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem
Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem
Friend WithEvents BTT_CONTEXT_ERASE As ToolStripMenuItem Friend WithEvents BTT_CONTEXT_ERASE As ToolStripMenuItem
@@ -98,6 +100,8 @@ Namespace API.Base
End If End If
End With End With
BTT_CONTEXT_DOWN = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = Me} BTT_CONTEXT_DOWN = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = Me}
BTT_CONTEXT_DOWN_LIMIT = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN_LIMIT"), .Tag = Me}
BTT_CONTEXT_DOWN_DATE = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN_DATE"), .Tag = Me}
BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = Me} BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = Me}
BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = Me} BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = Me}
BTT_CONTEXT_ERASE = New ToolStripMenuItem(tn, i) With {.Name = tnn("ERASE"), .Tag = Me} BTT_CONTEXT_ERASE = New ToolStripMenuItem(tn, i) With {.Name = tnn("ERASE"), .Tag = Me}
@@ -117,7 +121,8 @@ Namespace API.Base
cb = MyColor.EditBack cb = MyColor.EditBack
cf = MyColor.EditFore cf = MyColor.EditFore
End If End If
For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_ERASE, For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_DOWN_LIMIT, BTT_CONTEXT_DOWN_DATE,
BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_ERASE,
BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE} BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE}
If Not b Is Nothing Then b.BackColor = cb : b.ForeColor = cf If Not b Is Nothing Then b.BackColor = cb : b.ForeColor = cf
Next Next
@@ -410,9 +415,7 @@ Namespace API.Base
End Function End Function
Friend Overridable Sub SetPicture(ByVal f As SFile) Implements IUserData.SetPicture Friend Overridable Sub SetPicture(ByVal f As SFile) Implements IUserData.SetPicture
Try Try
If f.Exists Then If f.Exists Then UserImage.NewUserPicture(f, MyFile)
Using p As New UserImage(f, MyFile) : p.Save() : End Using
End If
Catch Catch
End Try End Try
End Sub End Sub
@@ -451,11 +454,7 @@ BlockPictureScan:
New ErrorsDescriber(EDP.ReturnValue) With { New ErrorsDescriber(EDP.ReturnValue) With {
.ReturnValue = New List(Of SFile), .ReturnValue = New List(Of SFile),
.ReturnValueExists = True}).FirstOrDefault .ReturnValueExists = True}).FirstOrDefault
If NewPicFile.Exists Then If NewPicFile.Exists Then p = UserImage.NewUserPicture(NewPicFile, MyFile,, True) : GoTo BlockReturn
p = New UserImage(NewPicFile, MyFile)
p.Save()
GoTo BlockReturn
End If
BlockDeletePictureFolder: BlockDeletePictureFolder:
On Error GoTo BlockReturn On Error GoTo BlockReturn
If DelPath Then If DelPath Then
@@ -654,6 +653,7 @@ BlockNullPicture:
End Sub End Sub
Protected ReadOnly _TempMediaList As List(Of UserMedia) Protected ReadOnly _TempMediaList As List(Of UserMedia)
Protected ReadOnly _TempPostsList As List(Of String) Protected ReadOnly _TempPostsList As List(Of String)
Private ReadOnly _MD5List As List(Of String)
Friend Function GetLastImageAddress() As SFile Friend Function GetLastImageAddress() As SFile
If _ContentList.Count > 0 Then If _ContentList.Count > 0 Then
Return _ContentList.LastOrDefault(Function(c) c.Type = UTypes.Picture And Not c.File.IsEmptyString And Not c.File.Extension = "gif").File Return _ContentList.LastOrDefault(Function(c) c.Type = UTypes.Picture And Not c.File.IsEmptyString And Not c.File.Extension = "gif").File
@@ -679,6 +679,7 @@ BlockNullPicture:
Protected MyFileSettings As SFile Protected MyFileSettings As SFile
Protected MyFileData As SFile Protected MyFileData As SFile
Protected MyFilePosts As SFile Protected MyFilePosts As SFile
Private MyMD5File As SFile
Friend Overridable Property FileExists As Boolean = False Implements IUserData.FileExists Friend Overridable Property FileExists As Boolean = False Implements IUserData.FileExists
Friend Overridable Property DataMerging As Boolean Friend Overridable Property DataMerging As Boolean
Get Get
@@ -856,6 +857,7 @@ BlockNullPicture:
LatestData = New List(Of UserMedia) LatestData = New List(Of UserMedia)
_TempMediaList = New List(Of UserMedia) _TempMediaList = New List(Of UserMedia)
_TempPostsList = New List(Of String) _TempPostsList = New List(Of String)
_MD5List = New List(Of String)
Labels = New List(Of String) Labels = New List(Of String)
UserUpdatedEventHandlers = New List(Of IUserData.UserUpdatedEventHandler) UserUpdatedEventHandlers = New List(Of IUserData.UserUpdatedEventHandler)
UserDownloadStateChangedEventHandlers = New List(Of UserDownloadStateChangedEventHandler) UserDownloadStateChangedEventHandlers = New List(Of UserDownloadStateChangedEventHandler)
@@ -950,6 +952,9 @@ BlockNullPicture:
LogError(ex, "user information loading error") LogError(ex, "user information loading error")
End Try End Try
End Sub End Sub
Private Sub UpdateUserInformation_Ex()
If _ForceSaveUserInfoOnException Then UpdateUserInformation()
End Sub
Friend Overridable Overloads Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation Friend Overridable Overloads Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation
UpdateUserInformation(False) UpdateUserInformation(False)
End Sub End Sub
@@ -1037,6 +1042,8 @@ BlockNullPicture:
If _ContentList.Count > 0 Then x.AddRange(_ContentList) If _ContentList.Count > 0 Then x.AddRange(_ContentList)
x.Save(MyFileData) x.Save(MyFileData)
End Using End Using
If Not MyMD5File.IsEmptyString And _MD5List.Count > 0 Then _
TextSaver.SaveTextToFile(_MD5List.ListToString(Environment.NewLine), MyMD5File, True,, EDP.None)
Catch ex As Exception Catch ex As Exception
LogError(ex, "history saving error") LogError(ex, "history saving error")
End Try End Try
@@ -1118,6 +1125,7 @@ BlockNullPicture:
Protected UseClientTokens As Boolean = False Protected UseClientTokens As Boolean = False
Protected _ForceSaveUserData As Boolean = False Protected _ForceSaveUserData As Boolean = False
Protected _ForceSaveUserInfo As Boolean = False Protected _ForceSaveUserInfo As Boolean = False
Protected _ForceSaveUserInfoOnException As Boolean = False
Private _DownloadInProgress As Boolean = False Private _DownloadInProgress As Boolean = False
Private _EnvirUserExists As Boolean Private _EnvirUserExists As Boolean
Private _EnvirUserSuspended As Boolean Private _EnvirUserSuspended As Boolean
@@ -1131,11 +1139,13 @@ BlockNullPicture:
TokenPersonal = Nothing TokenPersonal = Nothing
ProgressPre.Reset() ProgressPre.Reset()
UpdateDataFiles() UpdateDataFiles()
_MD5Loaded = False
_DownloadInProgress = True _DownloadInProgress = True
_DescriptionChecked = False _DescriptionChecked = False
_DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime _DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime
_ForceSaveUserData = False _ForceSaveUserData = False
_ForceSaveUserInfo = False _ForceSaveUserInfo = False
_ForceSaveUserInfoOnException = False
_EnvirUserExists = UserExists _EnvirUserExists = UserExists
_EnvirUserSuspended = UserSuspended _EnvirUserSuspended = UserSuspended
_EnvirCreatedByChannel = CreatedByChannel _EnvirCreatedByChannel = CreatedByChannel
@@ -1212,7 +1222,7 @@ BlockNullPicture:
ProgressPre.Done() ProgressPre.Done()
ThrowAny(Token) ThrowAny(Token)
If UseMD5Comparison And Not IsSubscription Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token) If RemoveExistingDuplicates And Not IsSubscription Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token)
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And Not __isChannelsSupport Then If _TempPostsList.Count > 0 And Not DownloadMissingOnly And Not __isChannelsSupport Then
If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd) If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd)
@@ -1265,9 +1275,11 @@ BlockNullPicture:
ThrowIfDisposed() ThrowIfDisposed()
If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated() If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated()
Catch oex As OperationCanceledException When Token.IsCancellationRequested Or TokenPersonal.IsCancellationRequested Or TokenQueue.IsCancellationRequested Catch oex As OperationCanceledException When Token.IsCancellationRequested Or TokenPersonal.IsCancellationRequested Or TokenQueue.IsCancellationRequested
UpdateUserInformation_Ex()
MyMainLOG = $"{ToStringForLog()}: downloading canceled" MyMainLOG = $"{ToStringForLog()}: downloading canceled"
Canceled = True Canceled = True
Catch exit_ex As ExitException Catch exit_ex As ExitException
UpdateUserInformation_Ex()
If Not exit_ex.Silent Then If Not exit_ex.Silent Then
If exit_ex.SimpleLogLine Then If exit_ex.SimpleLogLine Then
MyMainLOG = $"{ToStringForLog()}: downloading interrupted (exit) ({exit_ex.Message})" MyMainLOG = $"{ToStringForLog()}: downloading interrupted (exit) ({exit_ex.Message})"
@@ -1275,11 +1287,14 @@ BlockNullPicture:
ErrorsDescriber.Execute(EDP.SendToLog, exit_ex, $"{ToStringForLog()}: downloading interrupted (exit)") ErrorsDescriber.Execute(EDP.SendToLog, exit_ex, $"{ToStringForLog()}: downloading interrupted (exit)")
End If End If
End If End If
If _EnvirInvokeUserUpdated Then OnUserUpdated()
Canceled = True Canceled = True
Catch dex As ObjectDisposedException When Disposed Catch dex As ObjectDisposedException When Disposed
Canceled = True Canceled = True
Catch ex As Exception Catch ex As Exception
UpdateUserInformation_Ex()
LogError(ex, "downloading data error") LogError(ex, "downloading data error")
If _EnvirInvokeUserUpdated Then OnUserUpdated()
HasError = True HasError = True
Finally Finally
If Not UserExists Then AddNonExistingUserToLog($"User '{ToStringForLog()}' not found on the site") If Not UserExists Then AddNonExistingUserToLog($"User '{ToStringForLog()}' not found on the site")
@@ -1315,6 +1330,11 @@ BlockNullPicture:
MyFilePosts = MyFileSettings MyFilePosts = MyFileSettings
MyFilePosts.Name &= "_Posts" MyFilePosts.Name &= "_Posts"
MyFilePosts.Extension = "txt" MyFilePosts.Extension = "txt"
If Not IsSavedPosts Then
MyMD5File = MyFileSettings
MyMD5File.Name &= "_MD5"
MyMD5File.Extension = "txt"
End If
Else Else
Throw New ArgumentNullException("User.File", "User file not detected") Throw New ArgumentNullException("User.File", "User file not detected")
End If End If
@@ -1438,81 +1458,94 @@ BlockNullPicture:
End Sub End Sub
#End Region #End Region
#Region "MD5 support" #Region "MD5 support"
Protected Const VALIDATE_MD5_ERROR As String = "VALIDATE_MD5_ERROR" Private Const VALIDATE_MD5_ERROR As String = "VALIDATE_MD5_ERROR"
Friend Property UseMD5Comparison As Boolean = False Friend Property UseMD5Comparison As Boolean = False
Protected Property StartMD5Checked As Boolean = False Protected Property StartMD5Checked As Boolean = False
Friend Property RemoveExistingDuplicates As Boolean = False Friend Property RemoveExistingDuplicates As Boolean = False
Protected Overridable Sub ValidateMD5(ByVal Token As CancellationToken) Private ReadOnly ErrMD5 As New ErrorsDescriber(EDP.ReturnValue)
Private _MD5Loaded As Boolean = False
Private Sub LoadMD5()
Try
If Not _MD5Loaded Then
_MD5Loaded = True
_MD5List.Clear()
If _ContentList.Count > 0 Then _MD5List.ListAddList(_ContentList.Select(Function(c) c.MD5), LAP.NotContainsOnly, EDP.ReturnValue)
If MyMD5File.Exists Then _MD5List.ListAddList(MyMD5File.GetLines, LAP.NotContainsOnly, EDP.ThrowException)
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "LoadMD5")
End Try
End Sub
Private Function ValidateMD5_GetMD5(ByVal __data As UserMedia, ByVal IsUrl As Boolean) As String
Try
Dim ImgFormat As Imaging.ImageFormat = Nothing
Dim hash$ = String.Empty
Dim __isGif As Boolean = False
If __data.Type = UTypes.GIF Then
ImgFormat = Imaging.ImageFormat.Gif
__isGif = True
ElseIf Not __data.File.IsEmptyString Then
ImgFormat = GetImageFormat(__data.File)
End If
If ImgFormat Is Nothing Then ImgFormat = Imaging.ImageFormat.Jpeg
If IsUrl And Not __isGif Then
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ImgFormat, ErrMD5))
ElseIf IsUrl And __isGif Then
hash = ByteArrayToString(GetMD5FromBytes(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ErrMD5))
Else
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
End If
If hash.IsEmptyString And Not __isGif Then
If ImgFormat Is Imaging.ImageFormat.Jpeg Then ImgFormat = Imaging.ImageFormat.Png Else ImgFormat = Imaging.ImageFormat.Jpeg
If IsUrl Then
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ImgFormat, ErrMD5))
Else
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
End If
End If
Return hash
Catch
Return String.Empty
End Try
End Function
Private Sub ValidateMD5(ByVal Token As CancellationToken)
Try Try
Dim missingMD5 As Predicate(Of UserMedia) = Function(d) (d.Type = UTypes.GIF Or d.Type = UTypes.Picture) And d.MD5.IsEmptyString Dim missingMD5 As Predicate(Of UserMedia) = Function(d) (d.Type = UTypes.GIF Or d.Type = UTypes.Picture) And d.MD5.IsEmptyString
If UseMD5Comparison And _TempMediaList.Exists(missingMD5) Then If RemoveExistingDuplicates Then
RemoveExistingDuplicates = False
_ForceSaveUserInfo = True
LoadMD5()
Dim i% Dim i%
Dim itemsCount% = 0 Dim itemsCount% = 0
Dim limit% = If(DownloadTopCount, 0) Dim limit% = If(DownloadTopCount, 0)
Dim data As UserMedia = Nothing Dim data As UserMedia = Nothing
Dim hashList As New Dictionary(Of String, SFile)
Dim f As SFile Dim f As SFile
Dim ErrMD5 As New ErrorsDescriber(EDP.ReturnValue)
Dim __getMD5 As Func(Of UserMedia, Boolean, String) =
Function(ByVal __data As UserMedia, ByVal IsUrl As Boolean) As String
Try
Dim ImgFormat As Imaging.ImageFormat = Nothing
Dim hash$ = String.Empty
Dim __isGif As Boolean = False
If __data.Type = UTypes.GIF Then
ImgFormat = Imaging.ImageFormat.Gif
__isGif = True
ElseIf Not __data.File.IsEmptyString Then
ImgFormat = GetImageFormat(__data.File)
End If
If ImgFormat Is Nothing Then ImgFormat = Imaging.ImageFormat.Jpeg
If IsUrl And Not __isGif Then
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ImgFormat, ErrMD5))
ElseIf IsUrl And __isGif Then
hash = ByteArrayToString(GetMD5FromBytes(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ErrMD5))
Else
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
End If
If hash.IsEmptyString And Not __isGif Then
If ImgFormat Is Imaging.ImageFormat.Jpeg Then ImgFormat = Imaging.ImageFormat.Png Else ImgFormat = Imaging.ImageFormat.Jpeg
If IsUrl Then
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ImgFormat, ErrMD5))
Else
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
End If
End If
Return hash
Catch
Return String.Empty
End Try
End Function
If Not StartMD5Checked Then If Not StartMD5Checked Then
StartMD5Checked = True StartMD5Checked = True
If _ContentList.Exists(missingMD5) Then Dim existingFiles As List(Of SFile) = SFile.GetFiles(MyFileSettings.CutPath, "*.jpg|*.jpeg|*.png|*.gif",, EDP.ReturnValue).ListIfNothing
Dim existingFiles As List(Of SFile) = SFile.GetFiles(MyFileSettings.CutPath, "*.jpg|*.jpeg|*.png|*.gif",, EDP.ReturnValue).ListIfNothing Dim eIndx%
Dim eIndx% Dim eFinder As Predicate(Of SFile) = Function(ff) ff.File = data.File.File
Dim eFinder As Predicate(Of SFile) = Function(ff) ff.File = data.File.File
If RemoveExistingDuplicates Then If existingFiles.Count > 0 Then
RemoveExistingDuplicates = False Dim h$
_ForceSaveUserInfo = True ProgressPre.ChangeMax(existingFiles.Count)
If existingFiles.Count > 0 Then For i = existingFiles.Count - 1 To 0 Step -1
Dim h$ ProgressPre.Perform()
ProgressPre.ChangeMax(existingFiles.Count) h = ValidateMD5_GetMD5(New UserMedia With {.File = existingFiles(i)}, False)
For i = existingFiles.Count - 1 To 0 Step -1 If Not h.IsEmptyString Then
ProgressPre.Perform() If _MD5List.Contains(h) Then
h = __getMD5(New UserMedia With {.File = existingFiles(i)}, False) MyMainLOG = $"{ToStringForLog()}: Removed image [{existingFiles(i).File}] (duplicate)"
If Not h.IsEmptyString Then existingFiles(i).Delete(SFO.File, SFODelete.DeleteToRecycleBin, ErrMD5)
If hashList.ContainsKey(h) Then existingFiles.RemoveAt(i)
MyMainLOG = $"{ToStringForLog()}: Removed image [{existingFiles(i).File}] (duplicate of [{hashList(h).File}])" Else
existingFiles(i).Delete(SFO.File, SFODelete.DeleteToRecycleBin, ErrMD5) _MD5List.Add(h)
existingFiles.RemoveAt(i) End If
Else
hashList.Add(h, existingFiles(i))
End If
End If
Next
End If End If
End If Next
End If
If _ContentList.Count > 0 AndAlso _ContentList.Exists(missingMD5) Then
ProgressPre.ChangeMax(_ContentList.Count) ProgressPre.ChangeMax(_ContentList.Count)
For i = 0 To _ContentList.Count - 1 For i = 0 To _ContentList.Count - 1
data = _ContentList(i) data = _ContentList(i)
@@ -1522,61 +1555,34 @@ BlockNullPicture:
ThrowAny(Token) ThrowAny(Token)
eIndx = existingFiles.FindIndex(eFinder) eIndx = existingFiles.FindIndex(eFinder)
If eIndx >= 0 Then If eIndx >= 0 Then
data.MD5 = __getMD5(New UserMedia With {.File = existingFiles(eIndx)}, False) data.MD5 = ValidateMD5_GetMD5(New UserMedia With {.File = existingFiles(eIndx)}, False)
If Not data.MD5.IsEmptyString Then _ContentList(i) = data : _ForceSaveUserData = True If Not data.MD5.IsEmptyString Then _ContentList(i) = data : _ForceSaveUserData = True
End If End If
End If End If
existingFiles.RemoveAll(eFinder) existingFiles.RemoveAll(eFinder)
End If End If
Next Next
If existingFiles.Count > 0 Then
ProgressPre.ChangeMax(existingFiles.Count)
For i = 0 To existingFiles.Count - 1
f = existingFiles(i)
ProgressPre.Perform()
data = New UserMedia(f.File) With {
.State = UStates.Downloaded,
.Type = IIf(f.Extension = "gif", UTypes.GIF, UTypes.Picture),
.File = f
}
ThrowAny(Token)
data.MD5 = __getMD5(data, False)
If Not data.MD5.IsEmptyString Then _ContentList.Add(data) : _ForceSaveUserData = True
Next
existingFiles.Clear()
End If
End If End If
End If
If _ContentList.Count > 0 Then If existingFiles.Count > 0 Then
With _ContentList.Select(Function(d) d.MD5) ProgressPre.ChangeMax(existingFiles.Count)
If .ListExists Then .ToList.ForEach(Sub(md5value) _ For i = 0 To existingFiles.Count - 1
If Not md5value.IsEmptyString AndAlso Not hashList.ContainsKey(md5value) Then hashList.Add(md5value, New SFile)) f = existingFiles(i)
End With ProgressPre.Perform()
End If data = New UserMedia(f.File) With {
.State = UStates.Downloaded,
ProgressPre.ChangeMax(_TempMediaList.Count) .Type = IIf(f.Extension = "gif", UTypes.GIF, UTypes.Picture),
For i = _TempMediaList.Count - 1 To 0 Step -1 .File = f
ProgressPre.Perform() }
If limit > 0 And itemsCount >= limit Then
_TempMediaList.RemoveAt(i)
Else
data = _TempMediaList(i)
If missingMD5(data) Then
ThrowAny(Token) ThrowAny(Token)
data.MD5 = __getMD5(data, True) data.MD5 = ValidateMD5_GetMD5(data, False)
If Not data.MD5.IsEmptyString Then If Not data.MD5.IsEmptyString Then _ContentList.Add(data) : _ForceSaveUserData = True
If hashList.ContainsKey(data.MD5) Then Next
_TempMediaList.RemoveAt(i) existingFiles.Clear()
Else
hashList.Add(data.MD5, New SFile)
_TempMediaList(i) = data
itemsCount += 1
End If
End If
End If
End If End If
Next End If
If _ContentList.Count > 0 Then _MD5List.ListAddList(_ContentList.Select(Function(d) d.MD5), LAP.NotContainsOnly, EDP.ReturnValue)
End If End If
Catch iex As ArgumentOutOfRangeException When Disposed Catch iex As ArgumentOutOfRangeException When Disposed
Catch ex As Exception Catch ex As Exception
@@ -1614,6 +1620,7 @@ BlockNullPicture:
Source.Progress.Done() Source.Progress.Done()
End Sub End Sub
End Class End Class
Protected Const VideoFolderName As String = "Video"
Protected Sub DownloadContentDefault(ByVal Token As CancellationToken) Protected Sub DownloadContentDefault(ByVal Token As CancellationToken)
Try Try
Dim i% Dim i%
@@ -1622,6 +1629,7 @@ BlockNullPicture:
If _ContentNew.Count > 0 Then If _ContentNew.Count > 0 Then
_ContentNew.RemoveAll(Function(c) c.URL.IsEmptyString) _ContentNew.RemoveAll(Function(c) c.URL.IsEmptyString)
If _ContentNew.Count > 0 Then If _ContentNew.Count > 0 Then
If UseMD5Comparison Then LoadMD5()
MyFile.Exists(SFO.Path) MyFile.Exists(SFO.Path)
Dim MissingErrorsAdd As Boolean = Settings.AddMissingErrorsToLog Dim MissingErrorsAdd As Boolean = Settings.AddMissingErrorsToLog
Dim MyDir$ = DownloadContentDefault_GetRootDir() Dim MyDir$ = DownloadContentDefault_GetRootDir()
@@ -1630,6 +1638,7 @@ BlockNullPicture:
Dim __interrupt As Boolean Dim __interrupt As Boolean
Dim f As SFile Dim f As SFile
Dim v As UserMedia Dim v As UserMedia
Dim __fileDeleted As Boolean
Dim fileNumProvider As SFileNumbers = SFileNumbers.Default Dim fileNumProvider As SFileNumbers = SFileNumbers.Default
Dim __deleteFile As Action(Of SFile, String) = Sub(ByVal FileToDelete As SFile, ByVal FileUrl As String) Dim __deleteFile As Action(Of SFile, String) = Sub(ByVal FileToDelete As SFile, ByVal FileUrl As String)
Try Try
@@ -1641,9 +1650,21 @@ BlockNullPicture:
ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex) ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex)
End Try End Try
End Sub End Sub
Dim updateDownCount As Action = Sub()
Dim __n% = IIf(__fileDeleted, -1, 1)
If __isVideo Then
v.Type = UTypes.Video
DownloadedVideos(False) += __n
ElseIf v.Type = UTypes.GIF Then
DownloadedPictures(False) += __n
Else
v.Type = UTypes.Picture
DownloadedPictures(False) += __n
End If
End Sub
Using w As New OptionalWebClient(Me) Using w As New OptionalWebClient(Me)
If vsf Then CSFileP($"{MyDir}\Video\").Exists(SFO.Path) If vsf Then CSFileP($"{MyDir}\{VideoFolderName}\").Exists(SFO.Path)
Progress.Maximum += _ContentNew.Count Progress.Maximum += _ContentNew.Count
If IsSingleObjectDownload Then If IsSingleObjectDownload Then
If _ContentNew.Count = 1 And _ContentNew(0).Type = UTypes.Video Then If _ContentNew.Count = 1 And _ContentNew(0).Type = UTypes.Video Then
@@ -1671,6 +1692,8 @@ BlockNullPicture:
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
__fileDeleted = False
If Not f.IsEmptyString And Not v.URL.IsEmptyString Then If Not f.IsEmptyString And Not v.URL.IsEmptyString Then
Try Try
__isVideo = v.Type = UTypes.Video Or f.Extension = "mp4" Or v.Type = UTypes.m3u8 __isVideo = v.Type = UTypes.Video Or f.Extension = "mp4" Or v.Type = UTypes.m3u8
@@ -1691,7 +1714,7 @@ BlockNullPicture:
End If End If
If __isVideo And vsf Then If __isVideo And vsf Then
If v.SpecialFolder.IsEmptyString OrElse Not v.SpecialFolder.EndsWith("*") Then If v.SpecialFolder.IsEmptyString OrElse Not v.SpecialFolder.EndsWith("*") Then
f.Path = $"{f.PathWithSeparator}Video" f.Path = $"{f.PathWithSeparator}{VideoFolderName}"
If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path) If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
End If End If
End If End If
@@ -1715,19 +1738,26 @@ BlockNullPicture:
End If End If
End If End If
If __isVideo Then updateDownCount()
v.Type = UTypes.Video
DownloadedVideos(False) += 1
ElseIf v.Type = UTypes.GIF Then
DownloadedPictures(False) += 1
Else
v.Type = UTypes.Picture
DownloadedPictures(False) += 1
End If
v.File = ChangeFileNameByProvider(f, v) v.File = ChangeFileNameByProvider(f, v)
v.State = UStates.Downloaded v.State = UStates.Downloaded
DownloadContentDefault_PostProcessing(v, f, Token) DownloadContentDefault_PostProcessing(v, f, Token)
If UseMD5Comparison And (v.Type = UTypes.GIF Or v.Type = UTypes.Picture) Then
If v.File.Exists Then
v.MD5 = ValidateMD5_GetMD5(v, False)
If Not v.MD5.IsEmptyString Then
If _MD5List.Contains(v.MD5) Then
__fileDeleted = v.File.Delete(SFO.File, SFODelete.DeletePermanently, EDP.ReturnValue)
If __fileDeleted Then dCount -= 1 : updateDownCount()
Else
_MD5List.Add(v.MD5)
End If
End If
Else
dCount -= 1
End If
End If
dCount += 1 dCount += 1
Catch woex As OperationCanceledException When Token.IsCancellationRequested Catch woex As OperationCanceledException When Token.IsCancellationRequested
__deleteFile.Invoke(f, v.URL_BASE) __deleteFile.Invoke(f, v.URL_BASE)
@@ -1745,7 +1775,7 @@ BlockNullPicture:
Else Else
v.State = UStates.Skipped v.State = UStates.Skipped
End If End If
_ContentNew(i) = v If Not __fileDeleted Then _ContentNew(i) = v
If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then
Progress.Perform(_ContentNew.Count - dTotal) Progress.Perform(_ContentNew.Count - dTotal)
Exit Sub Exit Sub
@@ -1897,6 +1927,7 @@ BlockNullPicture:
If m.Contains(IUserData.EraseMode.History) Then If m.Contains(IUserData.EraseMode.History) Then
If MyFilePosts.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True If MyFilePosts.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
If MyFileData.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True If MyFileData.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
If MyMD5File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
LastUpdated = Nothing LastUpdated = Nothing
EraseData_AdditionalDataFiles() EraseData_AdditionalDataFiles()
UpdateUserInformation() UpdateUserInformation()
@@ -1913,6 +1944,8 @@ BlockNullPicture:
_TempMediaList.Clear() _TempMediaList.Clear()
_ContentNew.Clear() _ContentNew.Clear()
_ContentList.Clear() _ContentList.Clear()
_MD5List.Clear()
_MD5Loaded = False
End If End If
End If End If
End If End If
@@ -2165,6 +2198,12 @@ BlockNullPicture:
Private Sub BTT_CONTEXT_DOWN_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN.KeyClick Private Sub BTT_CONTEXT_DOWN_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN.KeyClick
Downloader.Add(Me, e.IncludeInTheFeed) Downloader.Add(Me, e.IncludeInTheFeed)
End Sub End Sub
Private Sub BTT_CONTEXT_DOWN_LIMIT_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN_LIMIT.KeyClick
ControlInvokeFast(MainFrameObj.MF, Sub() MainFrameObj.MF.DownloadSelectedUser(MainFrame.DownUserLimits.Number, e.IncludeInTheFeed, Me), EDP.SendToLog)
End Sub
Private Sub BTT_CONTEXT_DOWN_DATE_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_CONTEXT_DOWN_DATE.KeyClick
ControlInvokeFast(MainFrameObj.MF, Sub() MainFrameObj.MF.DownloadSelectedUser(MainFrame.DownUserLimits.Date, e.IncludeInTheFeed, Me), EDP.SendToLog)
End Sub
Private Sub BTT_CONTEXT_EDIT_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_EDIT.Click Private Sub BTT_CONTEXT_EDIT_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_EDIT.Click
Using f As New Editors.UserCreatorForm(Me) Using f As New Editors.UserCreatorForm(Me)
f.ShowDialog() f.ShowDialog()
@@ -2240,10 +2279,13 @@ BlockNullPicture:
LatestData.Clear() LatestData.Clear()
_TempMediaList.Clear() _TempMediaList.Clear()
_TempPostsList.Clear() _TempPostsList.Clear()
_MD5List.Clear()
TokenPersonal = Nothing TokenPersonal = Nothing
If Not ProgressPre Is Nothing Then ProgressPre.Reset() : ProgressPre.Dispose() If Not ProgressPre Is Nothing Then ProgressPre.Reset() : ProgressPre.Dispose()
If Not Responser Is Nothing Then Responser.Dispose() If Not Responser Is Nothing Then Responser.Dispose()
If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose() If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose()
If Not BTT_CONTEXT_DOWN_LIMIT Is Nothing Then BTT_CONTEXT_DOWN_LIMIT.Dispose()
If Not BTT_CONTEXT_DOWN_DATE Is Nothing Then BTT_CONTEXT_DOWN_DATE.Dispose()
If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose() If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose()
If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose() If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose()
If Not BTT_CONTEXT_ERASE Is Nothing Then BTT_CONTEXT_ERASE.Dispose() If Not BTT_CONTEXT_ERASE Is Nothing Then BTT_CONTEXT_ERASE.Dispose()

View File

@@ -7,8 +7,10 @@
' This program is distributed in the hope that it will be useful, ' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY ' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes Imports SCrawler.Plugin.Attributes
Imports DN = SCrawler.API.Base.DeclaredNames
Namespace API.Instagram Namespace API.Instagram
Friend Class EditorExchangeOptions Friend NotInheritable Class EditorExchangeOptions
#Region "Download"
<PSetting(Caption:="Get timeline", ToolTip:="Download user timeline")> <PSetting(Caption:="Get timeline", ToolTip:="Download user timeline")>
Friend Property GetTimeline As Boolean Friend Property GetTimeline As Boolean
<PSetting(Caption:="Get reels", ToolTip:="Download user reels")> <PSetting(Caption:="Get reels", ToolTip:="Download user reels")>
@@ -19,6 +21,27 @@ Namespace API.Instagram
Friend Property GetStoriesUser As Boolean Friend Property GetStoriesUser As Boolean
<PSetting(Caption:="Get tagged posts", ToolTip:="Download user tagged posts")> <PSetting(Caption:="Get tagged posts", ToolTip:="Download user tagged posts")>
Friend Property GetTagged As Boolean Friend Property GetTagged As Boolean
#End Region
#Region "Extract image"
<PSetting(Caption:="Extract image from video: timeline")>
Friend Property GetTimeline_VideoPic As Boolean
<PSetting(Caption:="Extract image from video: reels")>
Friend Property GetReels_VideoPic As Boolean
<PSetting(Caption:="Extract image from video: stories")>
Friend Property GetStories_VideoPic As Boolean
<PSetting(Caption:="Extract image from video: stories: user")>
Friend Property GetStoriesUser_VideoPic As Boolean
<PSetting(Caption:="Extract image from video: tagged posts")>
Friend Property GetTagged_VideoPic As Boolean
#End Region
<PSetting(Caption:="Place the extracted image into the video folder")>
Friend Property PutImageVideoFolder As Boolean
<PSetting(Address:=SettingAddress.User, Caption:=DN.UserNameChangeCaption, ToolTip:=DN.UserNameChangeToolTip)>
Friend Property UserName As String = String.Empty
<PSetting(Address:=SettingAddress.User, Caption:="Force update UserName", ToolTip:="Try to force update UserName if it is not found on the site")>
Friend Property ForceUpdateUserName As Boolean = False
<PSetting(Address:=SettingAddress.User, Caption:="Force update user information")>
Friend Property ForceUpdateUserInfo As Boolean = False
Friend Sub New(ByVal u As UserData) Friend Sub New(ByVal u As UserData)
With u With u
GetTimeline = .GetTimeline GetTimeline = .GetTimeline
@@ -26,6 +49,18 @@ Namespace API.Instagram
GetStories = .GetStories GetStories = .GetStories
GetStoriesUser = .GetStoriesUser GetStoriesUser = .GetStoriesUser
GetTagged = .GetTaggedData GetTagged = .GetTaggedData
GetTimeline_VideoPic = .GetTimeline_VideoPic
GetReels_VideoPic = .GetReels_VideoPic
GetStories_VideoPic = .GetStories_VideoPic
GetStoriesUser_VideoPic = .GetStoriesUser_VideoPic
GetTagged_VideoPic = .GetTaggedData_VideoPic
PutImageVideoFolder = .PutImageVideoFolder
UserName = .NameTrue(True)
ForceUpdateUserName = .ForceUpdateUserName
ForceUpdateUserInfo = .ForceUpdateUserInfo
End With End With
End Sub End Sub
Friend Sub New(ByVal s As SiteSettings) Friend Sub New(ByVal s As SiteSettings)
@@ -35,6 +70,14 @@ Namespace API.Instagram
GetStories = CBool(.GetStories.Value) GetStories = CBool(.GetStories.Value)
GetStoriesUser = CBool(.GetStoriesUser.Value) GetStoriesUser = CBool(.GetStoriesUser.Value)
GetTagged = CBool(.GetTagged.Value) GetTagged = CBool(.GetTagged.Value)
GetTimeline_VideoPic = CBool(.GetTimeline_VideoPic.Value)
GetReels_VideoPic = CBool(.GetReels_VideoPic.Value)
GetStories_VideoPic = CBool(.GetStories_VideoPic.Value)
GetStoriesUser_VideoPic = CBool(.GetStoriesUser_VideoPic.Value)
GetTagged_VideoPic = CBool(.GetTagged_VideoPic.Value)
PutImageVideoFolder = CBool(.PutImageVideoFolder.Value)
End With End With
End Sub End Sub
End Class End Class

View File

@@ -57,8 +57,11 @@ Namespace API.Instagram
#End Region #End Region
#Region "Categories" #Region "Categories"
Private Const CAT_DOWN As String = "Download data" Private Const CAT_DOWN As String = "Download data"
Private Const CAT_UserDefs_VIDEO As String = DN.CAT_UserDefs & ": extract image from video"
Private Const CAT_ERRORS As String = "Errors"
#End Region #End Region
#Region "Authorization properties" #Region "Properties"
#Region "Authorization"
Friend Const Header_IG_APP_ID As String = "x-ig-app-id" Friend Const Header_IG_APP_ID As String = "x-ig-app-id"
Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim" Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
Friend Const Header_CSRF_TOKEN As String = "x-csrftoken" Friend Const Header_CSRF_TOKEN As String = "x-csrftoken"
@@ -67,18 +70,18 @@ Namespace API.Instagram
Friend Const Header_Browser As String = "Sec-Ch-Ua" Friend Const Header_Browser As String = "Sec-Ch-Ua"
Friend Const Header_BrowserExt As String = "Sec-Ch-Ua-Full-Version-List" Friend Const Header_BrowserExt As String = "Sec-Ch-Ua-Full-Version-List"
Friend Const Header_Platform_Verion As String = "Sec-Ch-Ua-Platform-Version" Friend Const Header_Platform_Verion As String = "Sec-Ch-Ua-Platform-Version"
<PropertyOption(ControlText:="x-csrftoken", ControlToolTip:="Can be automatically extracted from cookies", IsAuth:=True, AllowNull:=True), ControlNumber(2), PClonable(Clone:=False)> <PropertyOption(ControlText:="x-csrftoken", ControlToolTip:="Can be automatically extracted from cookies", IsAuth:=True, AllowNull:=True), PClonable(Clone:=False)>
Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue
<CookieValueExtractor(NameOf(HH_CSRF_TOKEN))> <CookieValueExtractor(NameOf(HH_CSRF_TOKEN))>
Private Function GetValueFromCookies(ByVal PropName As String, ByVal c As CookieKeeper) As String Private Function GetValueFromCookies(ByVal PropName As String, ByVal c As CookieKeeper) As String
Return c.GetCookieValue(Header_CSRF_TOKEN_COOKIE, PropName, NameOf(HH_CSRF_TOKEN)) Return c.GetCookieValue(Header_CSRF_TOKEN_COOKIE, PropName, NameOf(HH_CSRF_TOKEN))
End Function End Function
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), ControlNumber(3), PClonable(Clone:=False)> <PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), PClonable(Clone:=False)>
Friend ReadOnly Property HH_IG_APP_ID As PropertyValue Friend ReadOnly Property HH_IG_APP_ID As PropertyValue
<PropertyOption(ControlText:="x-asbd-id", IsAuth:=True, AllowNull:=True), ControlNumber(4), PClonable(Clone:=False)> <PropertyOption(ControlText:="x-asbd-id", IsAuth:=True, AllowNull:=True), PClonable(Clone:=False)>
Friend ReadOnly Property HH_ASBD_ID As PropertyValue Friend ReadOnly Property HH_ASBD_ID As PropertyValue
'PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True) 'PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True)
<ControlNumber(5), PClonable(Clone:=False)> <PClonable(Clone:=False)>
Friend ReadOnly Property HH_IG_WWW_CLAIM As PropertyValue Friend ReadOnly Property HH_IG_WWW_CLAIM As PropertyValue
Private ReadOnly Property HH_IG_WWW_CLAIM_IS_ZERO As Boolean Private ReadOnly Property HH_IG_WWW_CLAIM_IS_ZERO As Boolean
Get Get
@@ -87,16 +90,16 @@ Namespace API.Instagram
End Get End Get
End Property End Property
<PropertyOption(ControlText:="sec-ch-ua", IsAuth:=True, AllowNull:=True, <PropertyOption(ControlText:="sec-ch-ua", IsAuth:=True, AllowNull:=True,
InheritanceName:=SettingsCLS.HEADER_DEF_sec_ch_ua), ControlNumber(6), PClonable, PXML(OnlyForChecked:=True)> InheritanceName:=SettingsCLS.HEADER_DEF_sec_ch_ua), PClonable, PXML(OnlyForChecked:=True)>
Private ReadOnly Property HH_BROWSER As PropertyValue Private ReadOnly Property HH_BROWSER As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua-full", ControlToolTip:="sec-ch-ua-full-version-list", IsAuth:=True, AllowNull:=True, <PropertyOption(ControlText:="sec-ch-ua-full", ControlToolTip:="sec-ch-ua-full-version-list", IsAuth:=True, AllowNull:=True,
InheritanceName:=SettingsCLS.HEADER_DEF_sec_ch_ua_full_version_list), ControlNumber(7), PClonable, PXML(OnlyForChecked:=True)> InheritanceName:=SettingsCLS.HEADER_DEF_sec_ch_ua_full_version_list), PClonable, PXML(OnlyForChecked:=True)>
Private ReadOnly Property HH_BROWSER_EXT As PropertyValue Private ReadOnly Property HH_BROWSER_EXT As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua-platform-ver", ControlToolTip:="sec-ch-ua-platform-version", IsAuth:=True, AllowNull:=True, LeftOffset:=135, <PropertyOption(ControlText:="sec-ch-ua-platform-ver", ControlToolTip:="sec-ch-ua-platform-version", IsAuth:=True, AllowNull:=True, LeftOffset:=135,
InheritanceName:=SettingsCLS.HEADER_DEF_sec_ch_ua_platform_version), ControlNumber(8), PClonable, PXML(OnlyForChecked:=True)> InheritanceName:=SettingsCLS.HEADER_DEF_sec_ch_ua_platform_version), PClonable, PXML(OnlyForChecked:=True)>
Private ReadOnly Property HH_PLATFORM As PropertyValue Private ReadOnly Property HH_PLATFORM As PropertyValue
<PropertyOption(ControlText:="UserAgent", IsAuth:=True, AllowNull:=True, <PropertyOption(ControlText:="UserAgent", IsAuth:=True, AllowNull:=True,
InheritanceName:=SettingsCLS.HEADER_DEF_UserAgent), ControlNumber(9), PClonable, PXML(OnlyForChecked:=True)> InheritanceName:=SettingsCLS.HEADER_DEF_UserAgent), PClonable, PXML(OnlyForChecked:=True)>
Private ReadOnly Property HH_USER_AGENT As PropertyValue Private ReadOnly Property HH_USER_AGENT As PropertyValue
Friend Overrides Function BaseAuthExists() As Boolean Friend Overrides Function BaseAuthExists() As Boolean
Return Responser.CookiesExists And ACheck(HH_IG_APP_ID.Value) And ACheck(HH_CSRF_TOKEN.Value) Return Responser.CookiesExists And ACheck(HH_IG_APP_ID.Value) And ACheck(HH_CSRF_TOKEN.Value)
@@ -125,99 +128,147 @@ Namespace API.Instagram
End If End If
End Sub End Sub
#Region "HH_IG_WWW_CLAIM" #Region "HH_IG_WWW_CLAIM"
<PropertyOption(ControlText:="ig-www-claim update interval", IsAuth:=True, LeftOffset:=150), PXML, ControlNumber(10), PClonable, HiddenControl> <PropertyOption(ControlText:="ig-www-claim update interval", IsAuth:=True, LeftOffset:=150), PXML, PClonable, HiddenControl>
Private ReadOnly Property HH_IG_WWW_CLAIM_UPDATE_INTERVAL As PropertyValue Private ReadOnly Property HH_IG_WWW_CLAIM_UPDATE_INTERVAL As PropertyValue
<PropertyOption(ControlText:="ig-www-claim: always 0", ControlToolTip:="Keep token value always = 0", IsAuth:=True), <PropertyOption(ControlText:="ig-www-claim: always 0", ControlToolTip:="Keep token value always = 0", IsAuth:=True),
PXML, ControlNumber(11), PClonable, HiddenControl> PXML, PClonable, HiddenControl>
Friend ReadOnly Property HH_IG_WWW_CLAIM_ALWAYS_ZERO As PropertyValue Friend ReadOnly Property HH_IG_WWW_CLAIM_ALWAYS_ZERO As PropertyValue
<PropertyOption(ControlText:="ig-www-claim: reset each session", ControlToolTip:="Set 'x-ig-www-claim' to '0' before each session", IsAuth:=True), <PropertyOption(ControlText:="ig-www-claim: reset each session", ControlToolTip:="Set 'x-ig-www-claim' to '0' before each session", IsAuth:=True),
PXML, ControlNumber(12), PClonable, HiddenControl> PXML, PClonable, HiddenControl>
Friend ReadOnly Property HH_IG_WWW_CLAIM_RESET_EACH_SESSION As PropertyValue Friend ReadOnly Property HH_IG_WWW_CLAIM_RESET_EACH_SESSION As PropertyValue
<PropertyOption(ControlText:="ig-www-claim: reset each target", ControlToolTip:="Set 'x-ig-www-claim' to '0' before each target", IsAuth:=True), <PropertyOption(ControlText:="ig-www-claim: reset each target", ControlToolTip:="Set 'x-ig-www-claim' to '0' before each target", IsAuth:=True),
PXML, ControlNumber(13), PClonable, HiddenControl> PXML, PClonable, HiddenControl>
Friend ReadOnly Property HH_IG_WWW_CLAIM_RESET_EACH_TARGET As PropertyValue Friend ReadOnly Property HH_IG_WWW_CLAIM_RESET_EACH_TARGET As PropertyValue
<PropertyOption(ControlText:="ig-www-claim: use in requests", IsAuth:=True), PXML, ControlNumber(14), PClonable, HiddenControl> <PropertyOption(ControlText:="ig-www-claim: use in requests", IsAuth:=True), PXML, PClonable, HiddenControl>
Friend ReadOnly Property HH_IG_WWW_CLAIM_USE As PropertyValue Friend ReadOnly Property HH_IG_WWW_CLAIM_USE As PropertyValue
<PropertyOption(ControlText:="ig-www-claim: use default algorithm to update", IsAuth:=True), PXML, ControlNumber(15), PClonable, HiddenControl> <PropertyOption(ControlText:="ig-www-claim: use default algorithm to update", IsAuth:=True), PXML, PClonable, HiddenControl>
Friend ReadOnly Property HH_IG_WWW_CLAIM_USE_DEFAULT_ALGO As PropertyValue Friend ReadOnly Property HH_IG_WWW_CLAIM_USE_DEFAULT_ALGO As PropertyValue
<Provider(NameOf(HH_IG_WWW_CLAIM_UPDATE_INTERVAL), FieldsChecker:=True)> <Provider(NameOf(HH_IG_WWW_CLAIM_UPDATE_INTERVAL), FieldsChecker:=True)>
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
#End Region #End Region
<PropertyOption(ControlText:="Use GraphQL to download", IsAuth:=True), PXML, ControlNumber(16), PClonable> <PropertyOption(ControlText:="Use GraphQL to download", IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property USE_GQL As PropertyValue Friend ReadOnly Property USE_GQL As PropertyValue
#End Region #End Region
#Region "Download properties" #Region "Download data"
<PropertyOption(ControlText:="DownDetector", <PropertyOption(ControlText:="Download timeline", Category:=CAT_DOWN), PXML, PClonable>
ControlToolTip:="Use 'DownDetector' to determine if the site is accessible. -1 to disable." & vbCr & Friend ReadOnly Property DownloadTimeline As PropertyValue
"The value represents the average number of error reports over the last 4 hours"), <PXML> Private ReadOnly Property DownloadTimeline_Def As PropertyValue
PClonable, PXML, ControlNumber(17)> <PropertyOption(ControlText:="Download reels", Category:=CAT_DOWN), PXML, PClonable>
Private ReadOnly Property DownDetectorValue As PropertyValue Friend ReadOnly Property DownloadReels As PropertyValue
<Provider(NameOf(DownDetectorValue), FieldsChecker:=True)> <PXML> Private ReadOnly Property DownloadReels_Def As PropertyValue
Private ReadOnly Property DownDetectorValueProvider As IFormatProvider <PropertyOption(ControlText:="Download stories", Category:=CAT_DOWN), PXML, PClonable>
<PropertyOption(ControlText:="Add 'DownDetector' information to the log."), PClonable, PXML, ControlNumber(18), HiddenControl> Friend ReadOnly Property DownloadStories As PropertyValue
Private ReadOnly Property DownDetectorValueAddToLog As PropertyValue <PXML> Private ReadOnly Property DownloadStories_Def As PropertyValue
<PropertyOption(ControlText:="Download stories: user", Category:=CAT_DOWN), PXML, PClonable>
Friend ReadOnly Property DownloadStoriesUser As PropertyValue
<PXML> Private ReadOnly Property DownloadStoriesUser_Def As PropertyValue
<PropertyOption(ControlText:="Download tagged posts", Category:=CAT_DOWN), PXML, PClonable>
Friend ReadOnly Property DownloadTagged As PropertyValue
<PXML> Private ReadOnly Property DownloadTagged_Def As PropertyValue
#End Region
#Region "Timers"
Friend Const TimersUrgentTip As String = vbCr & "It is highly recommended not to change the default value." Friend Const TimersUrgentTip As String = vbCr & "It is highly recommended not to change the default value."
<PropertyOption(ControlText:="Request timer (any)", <PropertyOption(ControlText:="Request timer (any)",
ControlToolTip:="The timer (in milliseconds) that SCrawler should wait before executing the next request." & ControlToolTip:="The timer (in milliseconds) that SCrawler should wait before executing the next request." &
vbCr & "The default value is 1'000." & vbCr & "The minimum value is 0." & TimersUrgentTip, AllowNull:=False, Category:=DN.CAT_Timers), vbCr & "The default value is 1'000." & vbCr & "The minimum value is 0." & TimersUrgentTip, AllowNull:=False, Category:=DN.CAT_Timers),
PXML, ControlNumber(19), PClonable> PXML, PClonable>
Friend ReadOnly Property RequestsWaitTimer_Any As PropertyValue Friend ReadOnly Property RequestsWaitTimer_Any As PropertyValue
<Provider(NameOf(RequestsWaitTimer_Any), FieldsChecker:=True)> <Provider(NameOf(RequestsWaitTimer_Any), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimer_AnyProvider As IFormatProvider Private ReadOnly Property RequestsWaitTimer_AnyProvider As IFormatProvider
<PropertyOption(ControlText:="Request timer", <PropertyOption(ControlText:="Request timer",
ControlToolTip:="The time value (in milliseconds) that the program will wait before processing the next 'Request time counter' request." & ControlToolTip:="The time value (in milliseconds) that the program will wait before processing the next 'Request time counter' request." &
vbCr & "The default value is 1'000." & vbCr & "The minimum value is 100." & TimersUrgentTip, vbCr & "The default value is 1'000." & vbCr & "The minimum value is 100." & TimersUrgentTip,
AllowNull:=False, Category:=DN.CAT_Timers), PXML, ControlNumber(20), PClonable> AllowNull:=False, Category:=DN.CAT_Timers), PXML, PClonable>
Friend ReadOnly Property RequestsWaitTimer As PropertyValue Friend ReadOnly Property RequestsWaitTimer As PropertyValue
<Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)> <Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider
<PropertyOption(ControlText:="Request timer counter", <PropertyOption(ControlText:="Request timer counter",
ControlToolTip:="How many requests will be sent to Instagram before the program waits 'Request timer'." & ControlToolTip:="How many requests will be sent to Instagram before the program waits 'Request timer'." &
vbCr & "The default value is 1." & vbCr & "The minimum value is 1." & TimersUrgentTip, vbCr & "The default value is 1." & vbCr & "The minimum value is 1." & TimersUrgentTip,
AllowNull:=False, LeftOffset:=120, Category:=DN.CAT_Timers), PXML, ControlNumber(21), PClonable> AllowNull:=False, LeftOffset:=120, Category:=DN.CAT_Timers), PXML, PClonable>
Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue
<Provider(NameOf(RequestsWaitTimerTaskCount), FieldsChecker:=True)> <Provider(NameOf(RequestsWaitTimerTaskCount), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider
<PropertyOption(ControlText:="Posts limit timer", <PropertyOption(ControlText:="Posts limit timer",
ControlToolTip:="The time value (in milliseconds) the program will wait before processing the next request after 195 requests." & ControlToolTip:="The time value (in milliseconds) the program will wait before processing the next request after 195 requests." &
vbCr & "The default value is 60'000." & vbCr & "The minimum value is 10'000." & TimersUrgentTip, vbCr & "The default value is 60'000." & vbCr & "The minimum value is 10'000." & TimersUrgentTip,
AllowNull:=False, Category:=DN.CAT_Timers), PXML, ControlNumber(22), PClonable> AllowNull:=False, Category:=DN.CAT_Timers), PXML, PClonable>
Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue
<Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)> <Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)>
Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider
<PropertyOption(ControlText:="Get timeline", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, ControlNumber(23), PClonable> #End Region
#Region "New user defaults"
<PropertyOption(ControlText:="Get timeline", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, PClonable>
Friend ReadOnly Property GetTimeline As PropertyValue Friend ReadOnly Property GetTimeline As PropertyValue
<PropertyOption(ControlText:="Get reels", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, ControlNumber(24), PClonable> <PropertyOption(ControlText:="From timeline", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property GetTimeline_VideoPic As PropertyValue
<PropertyOption(ControlText:="Get reels", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, PClonable>
Friend ReadOnly Property GetReels As PropertyValue Friend ReadOnly Property GetReels As PropertyValue
<PropertyOption(ControlText:="Get stories", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, ControlNumber(25), PClonable> <PropertyOption(ControlText:="From reels", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property GetReels_VideoPic As PropertyValue
<PropertyOption(ControlText:="Get stories", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, PClonable>
Friend ReadOnly Property GetStories As PropertyValue Friend ReadOnly Property GetStories As PropertyValue
<PropertyOption(ControlText:="Get stories: user", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, ControlNumber(26), PClonable> <PropertyOption(ControlText:="From stories", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property GetStories_VideoPic As PropertyValue
<PropertyOption(ControlText:="Get stories: user", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, PClonable>
Friend ReadOnly Property GetStoriesUser As PropertyValue Friend ReadOnly Property GetStoriesUser As PropertyValue
<PropertyOption(ControlText:="Get tagged photos", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, ControlNumber(27), PClonable> <PropertyOption(ControlText:="From stories: user", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property GetStoriesUser_VideoPic As PropertyValue
<PropertyOption(ControlText:="Get tagged posts", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, PClonable>
Friend ReadOnly Property GetTagged As PropertyValue Friend ReadOnly Property GetTagged As PropertyValue
<PropertyOption(ControlText:="From tagged posts", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property GetTagged_VideoPic As PropertyValue
<PropertyOption(ControlText:="From saved posts", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property GetSavedPosts_VideoPic As PropertyValue
<PropertyOption(ControlText:="Place the extracted image into the video folder", ControlToolTip:="Default value for new users", Category:=CAT_UserDefs_VIDEO), PXML, PClonable>
Friend ReadOnly Property PutImageVideoFolder As PropertyValue
#End Region
#Region "Errors"
Private Const ErrorsDefault As String = "572"
<PropertyOption(ControlText:="Skip errors",
ControlToolTip:="Skip the following errors (comma separated)." & vbCr &
"Facing these errors will not disable the download, but will add a simple line to the log.", Category:=CAT_ERRORS),
PClonable, PXML>
Private ReadOnly Property SkipErrors As PropertyValue
<PropertyOption(ControlText:="Add skipped errors to the log", Category:=CAT_ERRORS), PClonable, PXML>
Private ReadOnly Property SkipErrors_AddToLog As PropertyValue
<PropertyOption(ControlText:="Skip errors (exclude)",
ControlToolTip:="Exclude the following errors from being added to the log (comma separated)", Category:=CAT_ERRORS), PClonable, PXML>
Private ReadOnly Property SkipErrors_AddToLog_Silent As PropertyValue
Friend ReadOnly Property ErrorSpecialHandling(ByVal ErrCode As Integer) As Boolean
Get
With CStr(SkipErrors.Value) : Return Not .IsEmptyString AndAlso .Contains(ErrCode) : End With
End Get
End Property
Friend ReadOnly Property ErrorSpecialHandling_AddToLog(ByVal ErrCode As Integer) As Boolean
Get
With CStr(SkipErrors_AddToLog_Silent.Value)
Return CBool(SkipErrors_AddToLog.Value) AndAlso (.IsEmptyString OrElse Not .Contains(ErrCode))
End With
End Get
End Property
<PropertyOption(ControlText:="Ignore stories downloading errors (560)",
ControlToolTip:="If checked, error 560 will be skipped and the download will continue. Otherwise, the download will be interrupted.",
Category:=CAT_ERRORS), PClonable, PXML>
Friend ReadOnly Property IgnoreStoriesDownloadingErrors As PropertyValue
#End Region
#Region "Other params"
<PropertyOption(ControlText:="DownDetector",
ControlToolTip:="Use 'DownDetector' to determine if the site is accessible. -1 to disable." & vbCr &
"The value represents the average number of error reports over the last 4 hours"),
PClonable, PXML>
Private ReadOnly Property DownDetectorValue As PropertyValue
<Provider(NameOf(DownDetectorValue), FieldsChecker:=True)>
Private ReadOnly Property DownDetectorValueProvider As IFormatProvider
<PropertyOption(ControlText:="Add 'DownDetector' information to the log."), PClonable, PXML, HiddenControl>
Private ReadOnly Property DownDetectorValueAddToLog As PropertyValue
<PropertyOption(ControlText:="Tagged notify limit", <PropertyOption(ControlText:="Tagged notify limit",
ControlToolTip:="If the number of tagged posts exceeds this number you will be notified." & vbCr & ControlToolTip:="If the number of tagged posts exceeds this number you will be notified." & vbCr &
"-1 to disable"), PXML, ControlNumber(27), PClonable> "-1 to disable"), PXML, PClonable>
Friend ReadOnly Property TaggedNotifyLimit As PropertyValue Friend ReadOnly Property TaggedNotifyLimit As PropertyValue
<Provider(NameOf(TaggedNotifyLimit), FieldsChecker:=True)> <Provider(NameOf(TaggedNotifyLimit), FieldsChecker:=True)>
Private ReadOnly Property TaggedNotifyLimitProvider As IFormatProvider Private ReadOnly Property TaggedNotifyLimitProvider As IFormatProvider
#End Region #End Region
#Region "Download ready"
<PropertyOption(ControlText:="Download timeline", ControlToolTip:="Download timeline", Category:=CAT_DOWN), PXML, ControlNumber(10), PClonable>
Friend ReadOnly Property DownloadTimeline As PropertyValue
<PXML> Private ReadOnly Property DownloadTimeline_Def As PropertyValue
<PropertyOption(ControlText:="Download reels", ControlToolTip:="Download reels", Category:=CAT_DOWN), PXML, ControlNumber(11), PClonable>
Friend ReadOnly Property DownloadReels As PropertyValue
<PXML> Private ReadOnly Property DownloadReels_Def As PropertyValue
<PropertyOption(ControlText:="Download stories", ControlToolTip:="Download stories", Category:=CAT_DOWN), PXML, ControlNumber(12), PClonable>
Friend ReadOnly Property DownloadStories As PropertyValue
<PXML> Private ReadOnly Property DownloadStories_Def As PropertyValue
<PropertyOption(ControlText:="Download stories: user", ControlToolTip:="Download stories (user)", Category:=CAT_DOWN), PXML, ControlNumber(13), PClonable>
Friend ReadOnly Property DownloadStoriesUser As PropertyValue
<PXML> Private ReadOnly Property DownloadStoriesUser_Def As PropertyValue
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged posts", Category:=CAT_DOWN), PXML, ControlNumber(14), PClonable>
Friend ReadOnly Property DownloadTagged As PropertyValue
<PXML> Private ReadOnly Property DownloadTagged_Def As PropertyValue
#End Region #End Region
#Region "429 bypass" #Region "429 bypass"
<PXML("InstagramDownloadingErrorDate")> <PXML("InstagramDownloadingErrorDate")>
@@ -251,8 +302,40 @@ Namespace API.Instagram
End Get End Get
End Property End Property
Private Const LastDownloadDateResetInterval As Integer = 60 Private Const LastDownloadDateResetInterval As Integer = 60
Private TooManyRequestsReadyForCatch As Boolean = True
Friend Function GetWaitDate() As Date
With DownloadingErrorDate
If ACheck(Of Date)(.Value) Then
Return CDate(.Value).AddMinutes(If(LastApplyingValue, 10))
Else
Return Now
End If
End With
End Function
Friend Sub TooManyRequests(ByVal Catched As Boolean)
With DownloadingErrorDate
If Catched Then
If Not ACheck(Of Date)(.Value) Then
.Value = Now
If TooManyRequestsReadyForCatch Then
LastApplyingValue = If(LastApplyingValue, 0) + 10
TooManyRequestsReadyForCatch = False
MyMainLOG = $"Instagram downloading error: too many requests. Try again after {If(LastApplyingValue, 10)} minutes..."
End If
End If
Else
.Value = Nothing
LastApplyingValue = Nothing
TooManyRequestsReadyForCatch = True
End If
End With
End Sub
#End Region
#Region "LastRequestsCount, Label"
<PXML> Private ReadOnly Property LastDownloadDate As PropertyValue <PXML> Private ReadOnly Property LastDownloadDate As PropertyValue
<PXML> Private ReadOnly Property LastRequestsCount As PropertyValue <PXML> Private ReadOnly Property LastRequestsCount As PropertyValue
<PropertyOption(IsInformationLabel:=True)>
Private ReadOnly Property LastRequestsCountLabel As PropertyValue
Private ReadOnly MyLastRequests As Dictionary(Of Date, Integer) Private ReadOnly MyLastRequests As Dictionary(Of Date, Integer)
Private ReadOnly Property MyLastRequestsDate As Date Private ReadOnly Property MyLastRequestsDate As Date
Get Get
@@ -306,36 +389,6 @@ Namespace API.Instagram
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[SiteSettings.Instagram.RefreshMyLastRequests]") ErrorsDescriber.Execute(EDP.SendToLog, ex, "[SiteSettings.Instagram.RefreshMyLastRequests]")
End Try End Try
End Sub End Sub
<PropertyOption(IsInformationLabel:=True), ControlNumber(100)>
Private ReadOnly Property LastRequestsCountLabel As PropertyValue
Private TooManyRequestsReadyForCatch As Boolean = True
Friend Function GetWaitDate() As Date
With DownloadingErrorDate
If ACheck(Of Date)(.Value) Then
Return CDate(.Value).AddMinutes(If(LastApplyingValue, 10))
Else
Return Now
End If
End With
End Function
Friend Sub TooManyRequests(ByVal Catched As Boolean)
With DownloadingErrorDate
If Catched Then
If Not ACheck(Of Date)(.Value) Then
.Value = Now
If TooManyRequestsReadyForCatch Then
LastApplyingValue = If(LastApplyingValue, 0) + 10
TooManyRequestsReadyForCatch = False
MyMainLOG = $"Instagram downloading error: too many requests. Try again after {If(LastApplyingValue, 10)} minutes..."
End If
End If
Else
.Value = Nothing
LastApplyingValue = Nothing
TooManyRequestsReadyForCatch = True
End If
End With
End Sub
#End Region #End Region
#End Region #End Region
#Region "Initializer" #Region "Initializer"
@@ -412,9 +465,6 @@ Namespace API.Instagram
DownloadTagged = New PropertyValue(False) DownloadTagged = New PropertyValue(False)
DownloadTagged_Def = New PropertyValue(DownloadTagged.Value, GetType(Boolean)) DownloadTagged_Def = New PropertyValue(DownloadTagged.Value, GetType(Boolean))
DownDetectorValue = New PropertyValue(20)
DownDetectorValueProvider = New TimersChecker(-1)
DownDetectorValueAddToLog = New PropertyValue(False)
RequestsWaitTimer_Any = New PropertyValue(1000) RequestsWaitTimer_Any = New PropertyValue(1000)
RequestsWaitTimer_AnyProvider = New TimersChecker(0) RequestsWaitTimer_AnyProvider = New TimersChecker(0)
RequestsWaitTimer = New PropertyValue(1000) RequestsWaitTimer = New PropertyValue(1000)
@@ -425,10 +475,26 @@ Namespace API.Instagram
SleepTimerOnPostsLimitProvider = New TimersChecker(10000) SleepTimerOnPostsLimitProvider = New TimersChecker(10000)
GetTimeline = New PropertyValue(True) GetTimeline = New PropertyValue(True)
GetTimeline_VideoPic = New PropertyValue(True)
GetReels = New PropertyValue(False) GetReels = New PropertyValue(False)
GetReels_VideoPic = New PropertyValue(True)
GetStories = New PropertyValue(False) GetStories = New PropertyValue(False)
GetStories_VideoPic = New PropertyValue(True)
GetStoriesUser = New PropertyValue(False) GetStoriesUser = New PropertyValue(False)
GetStoriesUser_VideoPic = New PropertyValue(True)
GetTagged = New PropertyValue(False) GetTagged = New PropertyValue(False)
GetTagged_VideoPic = New PropertyValue(True)
GetSavedPosts_VideoPic = New PropertyValue(True)
PutImageVideoFolder = New PropertyValue(False)
SkipErrors = New PropertyValue(ErrorsDefault)
SkipErrors_AddToLog = New PropertyValue(True)
SkipErrors_AddToLog_Silent = New PropertyValue(String.Empty, GetType(String))
IgnoreStoriesDownloadingErrors = New PropertyValue(False)
DownDetectorValue = New PropertyValue(20)
DownDetectorValueProvider = New TimersChecker(-1)
DownDetectorValueAddToLog = New PropertyValue(False)
TaggedNotifyLimit = New PropertyValue(200) TaggedNotifyLimit = New PropertyValue(200)
TaggedNotifyLimitProvider = New TaggedNotifyLimitChecker TaggedNotifyLimitProvider = New TaggedNotifyLimitChecker
@@ -443,14 +509,18 @@ Namespace API.Instagram
UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "instagram.com/"), 1) UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "instagram.com/"), 1)
ImageVideoContains = "instagram.com" ImageVideoContains = "instagram.com"
End Sub End Sub
Private Const SettingsVersionCurrent As Integer = 2
Friend Overrides Sub EndInit() Friend Overrides Sub EndInit()
Try : MyLastRequests.Add(LastDownloadDate.Value, LastRequestsCount.Value) : Catch : End Try Try : MyLastRequests.Add(LastDownloadDate.Value, LastRequestsCount.Value) : Catch : End Try
If Not CBool(HH_IG_WWW_CLAIM_USE.Value) Then Responser.Headers.Remove(Header_IG_WWW_CLAIM) If Not CBool(HH_IG_WWW_CLAIM_USE.Value) Then Responser.Headers.Remove(Header_IG_WWW_CLAIM)
If CInt(SettingsVersion.Value) < 2 Then If CInt(SettingsVersion.Value) < SettingsVersionCurrent Then
SettingsVersion.Value = 2 SettingsVersion.Value = SettingsVersionCurrent
HH_IG_WWW_CLAIM_UPDATE_INTERVAL.Value = 120 HH_IG_WWW_CLAIM_UPDATE_INTERVAL.Value = 120
HH_IG_WWW_CLAIM_USE_DEFAULT_ALGO.Value = 1 HH_IG_WWW_CLAIM_ALWAYS_ZERO.Value = False
HH_IG_WWW_CLAIM_RESET_EACH_TARGET.Value = 0 HH_IG_WWW_CLAIM_RESET_EACH_SESSION.Value = True
HH_IG_WWW_CLAIM_RESET_EACH_TARGET.Value = True
HH_IG_WWW_CLAIM_USE.Value = True
HH_IG_WWW_CLAIM_USE_DEFAULT_ALGO.Value = True
End If End If
MyBase.EndInit() MyBase.EndInit()
End Sub End Sub

View File

@@ -194,7 +194,7 @@ Namespace API.Instagram
With j({"data", "xdt_api__v1__feed__reels_media__connection", "edges"}) With j({"data", "xdt_api__v1__feed__reels_media__connection", "edges"})
If .ListExists Then If .ListExists Then
ProgressPre.ChangeMax(.Count) ProgressPre.ChangeMax(.Count)
For Each n As EContainer In .Self : GetStoriesData_ParseSingleHighlight(n("node"), i, False, Token) : Next For Each n As EContainer In .Self : GetStoriesData_ParseSingleHighlight(n("node"), i, False, Token, Sections.Stories) : Next
End If End If
End With End With
End If End If
@@ -217,7 +217,7 @@ Namespace API.Instagram
Using j As EContainer = JsonDocument.Parse(r) Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then If j.ListExists Then
Dim i% = -1 Dim i% = -1
GetStoriesData_ParseSingleHighlight(j.ItemF({"data", "xdt_api__v1__feed__reels_media", "reels_media", 0}), i, True, Token) GetStoriesData_ParseSingleHighlight(j.ItemF({"data", "xdt_api__v1__feed__reels_media", "reels_media", 0}), i, True, Token, Sections.UserStories)
End If End If
End Using End Using
End If End If

View File

@@ -26,12 +26,20 @@ Namespace API.Instagram
Private Const Name_LastCursor As String = "LastCursor" Private Const Name_LastCursor As String = "LastCursor"
Private Const Name_FirstLoadingDone As String = "FirstLoadingDone" Private Const Name_FirstLoadingDone As String = "FirstLoadingDone"
Private Const Name_GetTimeline As String = "GetTimeline" Private Const Name_GetTimeline As String = "GetTimeline"
Private Const Name_GetTimeline_VideoPic As String = "GetTimeline_VideoPic"
Private Const Name_GetReels As String = "GetReels" Private Const Name_GetReels As String = "GetReels"
Private Const Name_GetReels_VideoPic As String = "GetReels_VideoPic"
Private Const Name_GetStories As String = "GetStories" Private Const Name_GetStories As String = "GetStories"
Private Const Name_GetStories_VideoPic As String = "GetStories_VideoPic"
Private Const Name_GetStoriesUser As String = "GetStoriesUser" Private Const Name_GetStoriesUser As String = "GetStoriesUser"
Private Const Name_GetStoriesUser_VideoPic As String = "GetStoriesUser_VideoPic"
Private Const Name_GetTagged As String = "GetTaggedData" Private Const Name_GetTagged As String = "GetTaggedData"
Private Const Name_GetTagged_VideoPic As String = "GetTaggedData_VideoPic"
Private Const Name_PutImageVideoFolder As String = "PutImageVideoFolder"
Private Const Name_TaggedChecked As String = "TaggedChecked" Private Const Name_TaggedChecked As String = "TaggedChecked"
Private Const Name_NameTrue As String = "NameTrue" Private Const Name_NameTrue As String = "NameTrue"
Private Const Name_ForceUpdateUserName As String = "ForceUpdateUserName"
Private Const Name_ForceUpdateUserInfo As String = "ForceUpdateUserInfo"
#End Region #End Region
#Region "Declarations" #Region "Declarations"
Protected Structure PostKV : Implements IEContainerProvider Protected Structure PostKV : Implements IEContainerProvider
@@ -79,17 +87,41 @@ Namespace API.Instagram
Private LastCursor As String = String.Empty Private LastCursor As String = String.Empty
Private FirstLoadingDone As Boolean = False Private FirstLoadingDone As Boolean = False
Friend Property GetTimeline As Boolean = True Friend Property GetTimeline As Boolean = True
Friend Property GetTimeline_VideoPic As Boolean = True
Friend Property GetReels As Boolean = False Friend Property GetReels As Boolean = False
Friend Property GetReels_VideoPic As Boolean = True
Friend Property GetStories As Boolean Friend Property GetStories As Boolean
Friend Property GetStories_VideoPic As Boolean = True
Friend Property GetStoriesUser As Boolean Friend Property GetStoriesUser As Boolean
Friend Property GetStoriesUser_VideoPic As Boolean = True
Friend Property GetTaggedData As Boolean Friend Property GetTaggedData As Boolean
Friend Property GetTaggedData_VideoPic As Boolean = True
Friend Property PutImageVideoFolder As Boolean = False
Private Function ExtractImageFrom(ByVal Section As Sections) As Boolean
Select Case Section
Case Sections.Timeline : Return GetTimeline_VideoPic
Case Sections.Reels : Return GetReels_VideoPic
Case Sections.Tagged : Return GetTaggedData_VideoPic
Case Sections.Stories : Return GetStories_VideoPic
Case Sections.UserStories : Return GetStoriesUser_VideoPic
Case Sections.SavedPosts
Try
If Not HOST Is Nothing AndAlso HOST.Key = InstagramSiteKey Then Return MySiteSettings.GetSavedPosts_VideoPic.Value
Catch
End Try
Return True
Case Else : Return True
End Select
End Function
Protected _NameTrue As String = String.Empty Protected _NameTrue As String = String.Empty
Friend ReadOnly Property NameTrue As String Friend ReadOnly Property NameTrue(Optional ByVal Exact As Boolean = False) As String
Get Get
Return _NameTrue.IfNullOrEmpty(Name) Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name))
End Get End Get
End Property End Property
Private UserNameRequested As Boolean = False Private UserNameRequested As Boolean = False
Friend Property ForceUpdateUserName As Boolean = False
Friend Property ForceUpdateUserInfo As Boolean = False
#End Region #End Region
#Region "Loader" #Region "Loader"
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean) Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
@@ -98,22 +130,38 @@ Namespace API.Instagram
LastCursor = .Value(Name_LastCursor) LastCursor = .Value(Name_LastCursor)
FirstLoadingDone = .Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False) FirstLoadingDone = .Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
GetTimeline = .Value(Name_GetTimeline).FromXML(Of Boolean)(CBool(MySiteSettings.GetTimeline.Value)) GetTimeline = .Value(Name_GetTimeline).FromXML(Of Boolean)(CBool(MySiteSettings.GetTimeline.Value))
GetReels = .Value(Name_GetReels).FromXML(Of Boolean)(MySiteSettings.GetReels.Value) GetTimeline_VideoPic = .Value(Name_GetTimeline_VideoPic).FromXML(Of Boolean)(CBool(MySiteSettings.GetTimeline_VideoPic.Value))
GetReels = .Value(Name_GetReels).FromXML(Of Boolean)(CBool(MySiteSettings.GetReels.Value))
GetReels_VideoPic = .Value(Name_GetReels_VideoPic).FromXML(Of Boolean)(CBool(MySiteSettings.GetReels_VideoPic.Value))
GetStories = .Value(Name_GetStories).FromXML(Of Boolean)(CBool(MySiteSettings.GetStories.Value)) GetStories = .Value(Name_GetStories).FromXML(Of Boolean)(CBool(MySiteSettings.GetStories.Value))
GetStoriesUser = .Value(Name_GetStoriesUser).FromXML(Of Boolean)(MySiteSettings.GetStoriesUser.Value) GetStories_VideoPic = .Value(Name_GetStories_VideoPic).FromXML(Of Boolean)(CBool(MySiteSettings.GetStories_VideoPic.Value))
GetStoriesUser = .Value(Name_GetStoriesUser).FromXML(Of Boolean)(CBool(MySiteSettings.GetStoriesUser.Value))
GetStoriesUser_VideoPic = .Value(Name_GetStoriesUser_VideoPic).FromXML(Of Boolean)(CBool(MySiteSettings.GetStoriesUser_VideoPic.Value))
PutImageVideoFolder = .Value(Name_PutImageVideoFolder).FromXML(Of Boolean)(CBool(MySiteSettings.PutImageVideoFolder.Value))
GetTaggedData = .Value(Name_GetTagged).FromXML(Of Boolean)(CBool(MySiteSettings.GetTagged.Value)) GetTaggedData = .Value(Name_GetTagged).FromXML(Of Boolean)(CBool(MySiteSettings.GetTagged.Value))
GetTaggedData_VideoPic = .Value(Name_GetTagged_VideoPic).FromXML(Of Boolean)(CBool(MySiteSettings.GetTagged_VideoPic.Value))
TaggedChecked = .Value(Name_TaggedChecked).FromXML(Of Boolean)(False) TaggedChecked = .Value(Name_TaggedChecked).FromXML(Of Boolean)(False)
_NameTrue = .Value(Name_NameTrue) _NameTrue = .Value(Name_NameTrue)
ForceUpdateUserName = .Value(Name_ForceUpdateUserName).FromXML(Of Boolean)(False)
ForceUpdateUserInfo = .Value(Name_ForceUpdateUserInfo).FromXML(Of Boolean)(False)
Else Else
.Add(Name_LastCursor, LastCursor) .Add(Name_LastCursor, LastCursor)
.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger) .Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
.Add(Name_GetTimeline, GetTimeline.BoolToInteger) .Add(Name_GetTimeline, GetTimeline.BoolToInteger)
.Add(Name_GetTimeline_VideoPic, GetTimeline_VideoPic.BoolToInteger)
.Add(Name_GetReels, GetReels.BoolToInteger) .Add(Name_GetReels, GetReels.BoolToInteger)
.Add(Name_GetReels_VideoPic, GetReels_VideoPic.BoolToInteger)
.Add(Name_GetStories, GetStories.BoolToInteger) .Add(Name_GetStories, GetStories.BoolToInteger)
.Add(Name_GetStories_VideoPic, GetStories_VideoPic.BoolToInteger)
.Add(Name_GetStoriesUser, GetStoriesUser.BoolToInteger) .Add(Name_GetStoriesUser, GetStoriesUser.BoolToInteger)
.Add(Name_GetStoriesUser_VideoPic, GetStoriesUser_VideoPic.BoolToInteger)
.Add(Name_GetTagged, GetTaggedData.BoolToInteger) .Add(Name_GetTagged, GetTaggedData.BoolToInteger)
.Add(Name_GetTagged_VideoPic, GetTaggedData_VideoPic.BoolToInteger)
.Add(Name_PutImageVideoFolder, PutImageVideoFolder.BoolToInteger)
.Add(Name_TaggedChecked, TaggedChecked.BoolToInteger) .Add(Name_TaggedChecked, TaggedChecked.BoolToInteger)
.Add(Name_NameTrue, _NameTrue) .Add(Name_NameTrue, _NameTrue)
.Add(Name_ForceUpdateUserName, ForceUpdateUserName.BoolToInteger)
.Add(Name_ForceUpdateUserInfo, ForceUpdateUserInfo.BoolToInteger)
End If End If
End With End With
End Sub End Sub
@@ -130,6 +178,18 @@ Namespace API.Instagram
GetStories = .GetStories GetStories = .GetStories
GetStoriesUser = .GetStoriesUser GetStoriesUser = .GetStoriesUser
GetTaggedData = .GetTagged GetTaggedData = .GetTagged
GetTimeline_VideoPic = .GetTimeline_VideoPic
GetReels_VideoPic = .GetReels_VideoPic
GetStories_VideoPic = .GetStories_VideoPic
GetStoriesUser_VideoPic = .GetStoriesUser_VideoPic
GetTaggedData_VideoPic = .GetTagged_VideoPic
PutImageVideoFolder = .PutImageVideoFolder
_NameTrue = .UserName
ForceUpdateUserName = .ForceUpdateUserName
ForceUpdateUserInfo = .ForceUpdateUserInfo
End With End With
End If End If
End Sub End Sub
@@ -147,15 +207,32 @@ Namespace API.Instagram
Private WwwClaimUse As Boolean = True Private WwwClaimUse As Boolean = True
Private E560Thrown As Boolean = False Private E560Thrown As Boolean = False
Friend Err5xx As Integer = -1 Friend Err5xx As Integer = -1
Private _ErrHandling As Integer = -1
Private Property ErrHandling As Integer
Get
Return _ErrHandling
End Get
Set(ByVal ErrCode As Integer)
_ErrHandling = ErrCode
Err5xx = ErrCode
End Set
End Property
Private ErrHandlingLog As Boolean = True
Private ErrHandlingSection As Sections = Sections.Timeline
Private Const ErrHandlingValue As Integer = 100
Private Const ErrHandlingValueStories As Integer = 150
Private Class ExitException : Inherits Exception Private Class ExitException : Inherits Exception
Friend Property Is560 As Boolean = False Friend Property Is560 As Boolean = False
Friend Property IsTokens As Boolean = False Friend Property IsTokens As Boolean = False
Friend Property TokensData As String = String.Empty Friend Property TokensData As String = String.Empty
Friend Shared Sub Throw560(ByRef Source As UserData) Friend Shared Sub Throw560(ByRef Source As UserData)
If Not Source.E560Thrown Then With Source
MyMainLOG = $"{Source.ToStringForLog}: ({IIf(Source.Err5xx > 0, Source.Err5xx, 560)}) Download skipped until next session" If Not .E560Thrown Then
Source.E560Thrown = True If .ErrHandling = -1 Or .ErrHandlingLog Then _
End If MyMainLOG = $"{ .ToStringForLog}: ({IIf(.Err5xx > 0, .Err5xx, 560)}) Download skipped {If(.ErrHandling = -1, "until next session", $"({ .ErrHandlingSection})")}"
.E560Thrown = True
End If
End With
Throw New ExitException With {.Is560 = True} Throw New ExitException With {.Is560 = True}
End Sub End Sub
Friend Shared Sub ThrowTokens(ByRef Source As UserData, ByVal Data As String) Friend Shared Sub ThrowTokens(ByRef Source As UserData, ByVal Data As String)
@@ -316,6 +393,9 @@ Namespace API.Instagram
Dim errorFound As Boolean = False Dim errorFound As Boolean = False
Try Try
Err5xx = -1 Err5xx = -1
ErrHandling = -1
ErrHandlingLog = True
ErrHandlingSection = Sections.Timeline
_Limit = If(DownloadTopCount, -1) _Limit = If(DownloadTopCount, -1)
_TotalPostsParsed = 0 _TotalPostsParsed = 0
LoadSavePostsKV(True) LoadSavePostsKV(True)
@@ -583,11 +663,13 @@ Namespace API.Instagram
'Check environment 'Check environment
If Not IsSavedPosts Then If Not IsSavedPosts Then
If ID.IsEmptyString Then GetUserData() If ID.IsEmptyString Then GetUserData()
If ID.IsEmptyString Then Throw New Plugin.ExitException("can't get user ID") If ID.IsEmptyString Then UserExists = False : _ForceSaveUserInfoOnException = True : Throw New Plugin.ExitException("can't get user ID")
If _UseGQL And Cursor.IsEmptyString And Not Section = Sections.SavedPosts Then If _UseGQL And Cursor.IsEmptyString And Not Section = Sections.SavedPosts Then
If Not ValidateBaseTokens() Then GetPageTokens() If Not ValidateBaseTokens() Then GetPageTokens()
If Not ValidateBaseTokens(TokensErrData) Then ValidateBaseTokens_Error(TokensErrData) If Not ValidateBaseTokens(TokensErrData) Then ValidateBaseTokens_Error(TokensErrData)
End If End If
If ForceUpdateUserName Then GetUserNameById()
If ForceUpdateUserInfo Then GetUserData()
End If End If
'Create query 'Create query
@@ -670,6 +752,14 @@ Namespace API.Instagram
Select Case Section Select Case Section
Case Sections.Timeline Case Sections.Timeline
With n With n
If If(n("user")?.Count, 0) = 0 And Cursor.IsEmptyString Then
If Not UserNameRequested Then
ForceUpdateUserName = True
Continue Do
Else
UserExists = False
End If
End If
HasNextPage = .Value("more_available").FromXML(Of Boolean)(False) HasNextPage = .Value("more_available").FromXML(Of Boolean)(False)
EndCursor = .Value("next_max_id") EndCursor = .Value("next_max_id")
If If(.Item("items")?.Count, 0) > 0 Then If If(.Item("items")?.Count, 0) > 0 Then
@@ -753,6 +843,11 @@ NextPageBlock:
Throw eex Throw eex
Catch ex As Exception Catch ex As Exception
dValue = ProcessException(ex, Token, $"data downloading error [{URL}]",, Section, False) dValue = ProcessException(ex, Token, $"data downloading error [{URL}]",, Section, False)
If dValue = ErrHandlingValue Then
ExitException.Throw560(Me)
ElseIf dValue = ErrHandlingValueStories Then
Exit Sub
End If
End Try End Try
Loop Loop
Catch jsonNull2 As JsonDocumentException When jsonNull2.State = WebDocumentEventArgs.States.Error And Catch jsonNull2 As JsonDocumentException When jsonNull2.State = WebDocumentEventArgs.States.Error And
@@ -809,7 +904,7 @@ NextPageBlock:
With j("items") With j("items")
For Each jj In .Self For Each jj In .Self
before = _TempMediaList.Count before = _TempMediaList.Count
ObtainMedia(jj, PostsToReparse(i).ID, specFolder) ObtainMedia(jj, PostsToReparse(i).ID, specFolder,,,,,,, IIf(IsTagged, Sections.Tagged, Sections.Timeline))
If Not before = _TempMediaList.Count Then _TotalPostsParsed += 1 If Not before = _TempMediaList.Count Then _TotalPostsParsed += 1
If _Limit > 0 And _TotalPostsParsed >= _Limit Then Throw New ExitException If _Limit > 0 And _TotalPostsParsed >= _Limit Then Throw New ExitException
Next Next
@@ -911,7 +1006,7 @@ NextPageBlock:
End Select End Select
End If End If
before = _TempMediaList.Count before = _TempMediaList.Count
ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate,, PostOriginUrl, State, Attempts) ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate,, PostOriginUrl, State, Attempts,, Section)
If Not before = _TempMediaList.Count Then _TotalPostsParsed += 1 If Not before = _TempMediaList.Count Then _TotalPostsParsed += 1
If _Limit > 0 And _TotalPostsParsed >= _Limit Then Return False If _Limit > 0 And _TotalPostsParsed >= _Limit Then Return False
End If End If
@@ -950,6 +1045,7 @@ NextPageBlock:
Protected ObtainMedia_SizeFuncVid As Func(Of EContainer, Sizes) = Nothing Protected ObtainMedia_SizeFuncVid As Func(Of EContainer, Sizes) = Nothing
Protected ObtainMedia_SizeFuncPic As Func(Of EContainer, Sizes) = Nothing Protected ObtainMedia_SizeFuncPic As Func(Of EContainer, Sizes) = Nothing
Protected ObtainMedia_AllowAbstract As Boolean = False Protected ObtainMedia_AllowAbstract As Boolean = False
Private Const ObtainMedia_NoSection As Integer = -10
Protected Sub ObtainMedia_SetReelsFunc() Protected Sub ObtainMedia_SetReelsFunc()
ObtainMedia_SizeFuncPic = Function(ByVal ss As EContainer) As Sizes ObtainMedia_SizeFuncPic = Function(ByVal ss As EContainer) As Sizes
If ss.Value("url").IsEmptyString Then If ss.Value("url").IsEmptyString Then
@@ -971,7 +1067,8 @@ NextPageBlock:
Optional ByVal DateObj As String = Nothing, Optional ByVal InitialType As Integer = -1, Optional ByVal DateObj As String = Nothing, Optional ByVal InitialType As Integer = -1,
Optional ByVal PostOriginUrl As String = Nothing, Optional ByVal PostOriginUrl As String = Nothing,
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal Attempts As Integer = 0, Optional ByVal State As UStates = UStates.Unknown, Optional ByVal Attempts As Integer = 0,
Optional ByVal TryExtractImage As Boolean = False) Optional ByVal TryExtractImage As Boolean = False,
Optional ByVal Section As Sections = ObtainMedia_NoSection)
Try Try
Dim maxSize As Func(Of EContainer, Integer) = Function(ByVal _ss As EContainer) As Integer Dim maxSize As Func(Of EContainer, Integer) = Function(ByVal _ss As EContainer) As Integer
Dim w% = AConvert(Of Integer)(_ss.Value("width"), 0) Dim w% = AConvert(Of Integer)(_ss.Value("width"), 0)
@@ -1018,6 +1115,12 @@ NextPageBlock:
If TryExtractImage Then If TryExtractImage Then
t = 1 t = 1
abstractDecision = True abstractDecision = True
If Not SpecialFolder.IsEmptyString AndAlso PutImageVideoFolder Then
Dim endsAbs As Boolean = SpecialFolder.EndsWith("*")
If endsAbs Then SpecialFolder = SpecialFolder.TrimEnd("*")
If Not SpecialFolder.IsEmptyString Then SpecialFolder = $"{SpecialFolder.TrimEnd("\")}\{VideoFolderName}{IIf(Not endsAbs, "*", String.Empty)}"
If endsAbs Then SpecialFolder &= "*"
End If
ElseIf t = -1 And InitialType = 8 And ObtainMedia_AllowAbstract Then ElseIf t = -1 And InitialType = 8 And ObtainMedia_AllowAbstract Then
If n.Contains(vid) Then If n.Contains(vid) Then
t = 2 t = 2
@@ -1064,7 +1167,8 @@ NextPageBlock:
End If End If
End With End With
End If End If
If Not TryExtractImage Then ObtainMedia(n, PostID, SpecialFolder, DateObj, InitialType, PostOriginUrl, State, Attempts, True) If Not TryExtractImage And Not Section = ObtainMedia_NoSection And ExtractImageFrom(Section) Then _
ObtainMedia(n, PostID, SpecialFolder, DateObj, InitialType, PostOriginUrl, State, Attempts, True, Section)
Case 8 'gallery Case 8 'gallery
DateObj = mDate(n) DateObj = mDate(n)
With n("carousel_media").XmlIfNothing With n("carousel_media").XmlIfNothing
@@ -1084,6 +1188,7 @@ NextPageBlock:
#Region "GetUserId, GetUserName" #Region "GetUserId, GetUserName"
Private Sub GetUserData() Private Sub GetUserData()
Dim __idFound As Boolean = False Dim __idFound As Boolean = False
If ForceUpdateUserInfo Then ForceUpdateUserInfo = False : _ForceSaveUserInfo = True
Try Try
ChangeResponserMode(False) ChangeResponserMode(False)
UpdateRequestNumber() UpdateRequestNumber()
@@ -1102,6 +1207,7 @@ NextPageBlock:
If Not eUrl.IsEmptyString AndAlso (descr.IsEmptyString OrElse Not descr.Contains(eUrl)) Then descr.StringAppendLine(eUrl) If Not eUrl.IsEmptyString AndAlso (descr.IsEmptyString OrElse Not descr.Contains(eUrl)) Then descr.StringAppendLine(eUrl)
UserDescriptionUpdate(descr) UserDescriptionUpdate(descr)
Dim f As New SFile With {.Path = DownloadContentDefault_GetRootDir(), .Name = "ProfilePicture", .Extension = "jpg"} Dim f As New SFile With {.Path = DownloadContentDefault_GetRootDir(), .Name = "ProfilePicture", .Extension = "jpg"}
f = SFile.IndexReindex(f)
If Not f.Exists Then If Not f.Exists Then
Dim profilePicture$ = .Value("profile_pic_url_hd") Dim profilePicture$ = .Value("profile_pic_url_hd")
If profilePicture.IsEmptyString OrElse Not GetWebFile(profilePicture, f, EDP.ReturnValue) Then If profilePicture.IsEmptyString OrElse Not GetWebFile(profilePicture, f, EDP.ReturnValue) Then
@@ -1114,6 +1220,7 @@ NextPageBlock:
End Using End Using
End If End If
Catch ex As Exception Catch ex As Exception
UserExists = False
If Not __idFound Then If Not __idFound Then
If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then
Throw ex Throw ex
@@ -1127,6 +1234,7 @@ NextPageBlock:
End Sub End Sub
Private Function GetUserNameById() As Boolean Private Function GetUserNameById() As Boolean
UserNameRequested = True UserNameRequested = True
If ForceUpdateUserName Then ForceUpdateUserName = False : _ForceSaveUserInfo = True
Try Try
If Not ID.IsEmptyString Then If Not ID.IsEmptyString Then
UpdateRequestNumber() UpdateRequestNumber()
@@ -1143,7 +1251,7 @@ NextPageBlock:
Dim descr$ = $"Username changed from '{oldName}' to '{newName}' ({Now.ToStringDate(ADateTime.Formats.BaseDateTime)})!" Dim descr$ = $"Username changed from '{oldName}' to '{newName}' ({Now.ToStringDate(ADateTime.Formats.BaseDateTime)})!"
descr.StringAppendLine(UserDescription) descr.StringAppendLine(UserDescription)
UserDescription = descr UserDescription = descr
_ForceSaveUserData = True _ForceSaveUserInfo = True
End If End If
Return True Return True
End If End If
@@ -1165,6 +1273,7 @@ NextPageBlock:
Dim qStr$, r$ Dim qStr$, r$
Dim i% = -1 Dim i% = -1
Dim jj As EContainer Dim jj As EContainer
Dim section As Sections = IIf(GetUserStory, Sections.UserStories, Sections.Stories)
ThrowAny(Token) ThrowAny(Token)
If StoriesList.ListExists Or GetUserStory Then If StoriesList.ListExists Or GetUserStory Then
If Not GetUserStory Then tmpList = StoriesList.Take(5) If Not GetUserStory Then tmpList = StoriesList.Take(5)
@@ -1181,7 +1290,7 @@ NextPageBlock:
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
If j.Contains("reels") Then If j.Contains("reels") Then
ProgressPre.ChangeMax(j("reels").Count) ProgressPre.ChangeMax(j("reels").Count)
For Each jj In j("reels") : GetStoriesData_ParseSingleHighlight(jj, i, GetUserStory, Token) : Next For Each jj In j("reels") : GetStoriesData_ParseSingleHighlight(jj, i, GetUserStory, Token, section) : Next
End If End If
End Using End Using
End If End If
@@ -1189,7 +1298,8 @@ NextPageBlock:
End If End If
End If End If
End Sub End Sub
Private Sub GetStoriesData_ParseSingleHighlight(ByVal Node As EContainer, ByRef Index As Integer, ByVal GetUserStory As Boolean, ByVal Token As CancellationToken) Private Sub GetStoriesData_ParseSingleHighlight(ByVal Node As EContainer, ByRef Index As Integer, ByVal GetUserStory As Boolean,
ByVal Token As CancellationToken, Optional ByVal Section As Sections = Sections.Stories)
If Not Node Is Nothing Then If Not Node Is Nothing Then
With Node With Node
ProgressPre.Perform() ProgressPre.Perform()
@@ -1210,7 +1320,7 @@ NextPageBlock:
pid = storyID & s.Value("id") pid = storyID & s.Value("id")
If Not _TempPostsList.Contains(pid) Then If Not _TempPostsList.Contains(pid) Then
ThrowAny(Token) ThrowAny(Token)
ObtainMedia(s, pid, sFolder) ObtainMedia(s, pid, sFolder,,,,,,, Section)
_TempPostsList.Add(pid) _TempPostsList.Add(pid)
End If End If
Next Next
@@ -1220,20 +1330,15 @@ NextPageBlock:
End If End If
End Sub End Sub
Private Function GetStoriesList() As List(Of String) Private Function GetStoriesList() As List(Of String)
Try UpdateRequestNumber()
UpdateRequestNumber() Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/highlights/{ID}/highlights_tray/",, EDP.ThrowException)
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/highlights/{ID}/highlights_tray/",, EDP.ThrowException) If Not r.IsEmptyString Then
If Not r.IsEmptyString Then Dim ee As New ErrorsDescriber(EDP.ReturnValue) With {.DeclaredMessage = New MMessage($"{ToStringForLog()}:")}
Dim ee As New ErrorsDescriber(EDP.ReturnValue) With {.DeclaredMessage = New MMessage($"{ToStringForLog()}:")} Using j As EContainer = JsonDocument.Parse(r, ee).XmlIfNothing()("tray").XmlIfNothing
Using j As EContainer = JsonDocument.Parse(r, ee).XmlIfNothing()("tray").XmlIfNothing If j.Count > 0 Then Return j.Select(Function(jj) jj.Value("id").Replace("highlight:", String.Empty)).ListIfNothing
If j.Count > 0 Then Return j.Select(Function(jj) jj.Value("id").Replace("highlight:", String.Empty)).ListIfNothing End Using
End Using End If
End If Return Nothing
Return Nothing
Catch ex As Exception
DownloadingException(ex, "API.Instagram.GetStoriesList", False, Sections.Stories)
Return Nothing
End Try
End Function End Function
#End Region #End Region
#Region "Download content" #Region "Download content"
@@ -1279,11 +1384,26 @@ NextPageBlock:
MyMainLOG = $"Number of requests before error 429: {RequestsCount}" MyMainLOG = $"Number of requests before error 429: {RequestsCount}"
Return 1 Return 1
ElseIf Responser.StatusCode = 560 Or Responser.StatusCode = HttpStatusCode.InternalServerError Then '560, 500 ElseIf Responser.StatusCode = 560 Or Responser.StatusCode = HttpStatusCode.InternalServerError Then '560, 500
MySiteSettings.SkipUntilNextSession = True If Responser.StatusCode = 560 And s = Sections.Stories And MySiteSettings.IgnoreStoriesDownloadingErrors Then
Err5xx = Responser.StatusCode MyMainLOG = $"{ToStringForLog()}: Stories downloading skipped (560)"
Return ErrHandlingValueStories
Else
MySiteSettings.SkipUntilNextSession = True
Err5xx = Responser.StatusCode
End If
ElseIf Responser.StatusCode = -1 And Responser.Status = -1 Then ElseIf Responser.StatusCode = -1 And Responser.Status = -1 Then
MySiteSettings.SkipUntilNextSession = True MySiteSettings.SkipUntilNextSession = True
Err5xx = Responser.StatusCode Err5xx = Responser.StatusCode
ElseIf MySiteSettings.ErrorSpecialHandling(Responser.StatusCode) Then
ErrHandlingLog = MySiteSettings.ErrorSpecialHandling_AddToLog(Responser.StatusCode)
ErrHandling = Responser.StatusCode
ErrHandlingSection = s
Return ErrHandlingValue
ElseIf MySiteSettings.ErrorSpecialHandling(Responser.Status) Then
ErrHandlingLog = MySiteSettings.ErrorSpecialHandling_AddToLog(Responser.Status)
ErrHandling = Responser.Status
ErrHandlingSection = s
Return ErrHandlingValue
Else Else
MyMainLOG = $"Something is wrong. Your credentials may have expired [{CInt(Responser.StatusCode)}/{CInt(Responser.Status)}]: {ToString()} [{s}]" MyMainLOG = $"Something is wrong. Your credentials may have expired [{CInt(Responser.StatusCode)}/{CInt(Responser.Status)}]: {ToString()} [{s}]"
DisableSection(s) DisableSection(s)

View File

@@ -15,6 +15,7 @@ Namespace API.Mastodon
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelSearch As Boolean <PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelSearch As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelForceApply As Boolean <PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelForceApply As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelLikes As Boolean <PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelLikes As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property UserName As String
Friend Sub New(ByVal s As SiteSettings) Friend Sub New(ByVal s As SiteSettings)
MyBase.New(s) MyBase.New(s)
End Sub End Sub

View File

@@ -11,15 +11,11 @@ Namespace API.OnlyFans
Friend Module Declarations Friend Module Declarations
Friend ReadOnly DateProvider As New ADateTime("O") Friend ReadOnly DateProvider As New ADateTime("O")
Friend ReadOnly RegExPostID As RParams = RParams.DM("(?<=onlyfans\.com/)(\d+)", 0, EDP.ReturnValue) Friend ReadOnly RegExPostID As RParams = RParams.DM("(?<=onlyfans\.com/)(\d+)", 0, EDP.ReturnValue)
Friend ReadOnly OFScraperConfigPatternFile As SFile = $"{SettingsFolderName}\OFScraperConfigPattern.json" Friend ReadOnly FilesSources As New List(Of Object()) From {
Friend Function CheckOFSConfig() As Boolean {{"source", "source"}},
If Not OFScraperConfigPatternFile.Exists Then {{"files", "source", "url"}},
Dim t$ = Text.Encoding.UTF8.GetString(My.Resources.OFResources.OFScraperConfigPattern) {{"files", "full", "url"}}
TextSaver.SaveTextToFile(t, OFScraperConfigPatternFile, True) }
Return OFScraperConfigPatternFile.Exists Friend Property Rules As DynamicRulesEnv
Else
Return True
End If
End Function
End Module End Module
End Namespace End Namespace

View File

@@ -0,0 +1,7 @@
https://github.com/datawhores/onlyfans-dynamic-rules/blob/main/dynamicRules.json
https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/main/dynamicRules.json
https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/patch-1/dynamicRules.json
https://github.com/DATAHOARDERS/dynamic-rules/blob/main/onlyfans.json
https://github.com/DIGITALCRIMINAL/dynamic-rules/blob/main/onlyfans.json
https://github.com/deviint/onlyfans-dynamic-rules/blob/main/dynamicRules.json
https://github.com/rafa-9/dynamic-rules/blob/main/rules.json

View File

@@ -0,0 +1,11 @@
https://github.com/datawhores/onlyfans-dynamic-rules/blob/main/dynamicRules.json
https://github.com/datawhores/onlyfans-dynamic-rules/blob/main/rules.json
https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/main/dynamicRules.json
https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/patch-1/dynamicRules.json
https://github.com/DATAHOARDERS/dynamic-rules/blob/main/onlyfans.json
https://github.com/DIGITALCRIMINAL/dynamic-rules/blob/main/onlyfans.json
https://github.com/deviint/onlyfans-dynamic-rules/blob/main/dynamicRules.json
https://github.com/rafa-9/dynamic-rules/blob/main/rules.json
https://github.com/SneakyOvis/onlyfans-dynamic-rules/blob/main/rules.json
https://github.com/Growik/onlyfans-dynamic-rules/blob/main/rules.json

View File

@@ -0,0 +1,753 @@
' Copyright (C) Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Clients.Base
Imports PersonalUtilities.Tools.Web.Documents.JSON
Imports System.Text.RegularExpressions
Namespace API.OnlyFans
Friend Structure DynamicRulesValue : Implements IComparable(Of DynamicRulesValue), IEquatable(Of DynamicRulesValue), IEContainerProvider
#Region "XML names"
Private Const Name_UrlRepo As String = "UrlRepo"
Private Const Name_UrlRaw As String = "UrlRaw"
Private Const Name_UrlLatestCommit As String = "UrlLatestCommit"
Private Const Name_UpdatedAt As String = "UpdatedAt"
Private Const Name_Broken As String = "Broken"
Private Const Name_Exists As String = "Exists"
#End Region
#Region "Declarations"
Friend UrlRepo As String
Friend UrlRaw As String
Friend UrlLatestCommit As String
Friend UpdatedAt As Date
Friend Broken As Boolean
Friend Exists As Boolean
Friend ReadOnly Property Valid As Boolean
Get
Return Not UrlRepo.IsEmptyString And Not UrlRaw.IsEmptyString
End Get
End Property
#End Region
#Region "Initializers"
Friend Sub New(ByVal e As EContainer)
UrlRepo = e.Value(Name_UrlRepo)
UrlRaw = e.Value(Name_UrlRaw)
UrlLatestCommit = e.Value(Name_UrlLatestCommit)
UpdatedAt = e.Value(Name_UpdatedAt).ToDateDef(Now.AddYears(-10))
Broken = e.Value(Name_Broken).FromXML(Of Boolean)(False)
Exists = e.Value(Name_Exists).FromXML(Of Boolean)(True)
End Sub
Public Shared Widening Operator CType(ByVal e As EContainer) As DynamicRulesValue
Return New DynamicRulesValue(e)
End Operator
Public Shared Widening Operator CType(ByVal rule As DynamicRulesValue) As String
Return rule.ToString
End Operator
#End Region
#Region "Base functions"
Public Overrides Function GetHashCode() As Integer
Return ToString.GetHashCode
End Function
Public Overrides Function ToString() As String
Return UrlRaw
End Function
#End Region
#Region "IComparable Support"
Private Function CompareTo(ByVal Other As DynamicRulesValue) As Integer Implements IComparable(Of DynamicRulesValue).CompareTo
Return UpdatedAt.CompareTo(Other.UpdatedAt) * -1
End Function
#End Region
#Region "IEquatable Support"
Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean
If Not IsNothing(Obj) Then
If TypeOf Obj Is String Then
Dim _obj$ = CStr(Obj).StringTrim.StringToLower
Return UrlRepo = _obj Or UrlRaw = _obj
Else
Return Equals(DirectCast(Obj, DynamicRulesValue))
End If
Else
Return False
End If
End Function
Friend Overloads Function Equals(ByVal Other As DynamicRulesValue) As Boolean Implements IEquatable(Of DynamicRulesValue).Equals
Return UrlRepo = Other.UrlRepo Or UrlRaw = Other.UrlRaw
End Function
#End Region
#Region "IEContainerProvider Support"
Private Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
Return New EContainer("Rule") From {
New EContainer(Name_UrlRepo, UrlRepo),
New EContainer(Name_UrlRaw, UrlRaw),
New EContainer(Name_UrlLatestCommit, UrlLatestCommit),
New EContainer(Name_UpdatedAt, UpdatedAt.ToStringDateDef),
New EContainer(Name_Broken, Broken.BoolToInteger),
New EContainer(Name_Exists, Exists.BoolToInteger)
}
End Function
#End Region
End Structure
Friend Class DynamicRulesEnv : Implements ICopier, IEnumerable(Of DynamicRulesValue), IMyEnumerator(Of DynamicRulesValue), IDisposable
Friend Enum Modes As Integer
List = 0
Personal = 1
End Enum
#Region "Constants"
Friend Const UpdateIntervalDefault As Integer = 1440 '60 * 24
Friend Const DynamicRulesConfigNodeName_URL As String = "DYNAMIC_GENERIC_URL"
Friend Const DynamicRulesConfigNodeName_RULES As String = "DYNAMIC_RULE"
Friend Const DynamicRulesConfig_Mode_NodeName As String = "dynamic-mode-default"
'Friend Const DynamicRulesConfig_Mode_NodeValue As String = "generic"
Friend Const DynamicRulesConfigNodeName_URL_CONST_NAME As String = "RULE_VALUE"
#End Region
#Region "XML names"
Private Const Name_LastUpdateTimeFile As String = "LastUpdateTimeFile"
Private Const Name_LastUpdateTimeRules As String = "LastUpdateTimeRules"
Private Const Name_ProtectFile As String = "ProtectFile"
Private Const Name_UpdateInterval As String = "UpdateInterval"
Private Const Name_Mode As String = "Mode"
Private Const Name_PersonalRule As String = "PersonalRule"
Private Const Name_RulesForceUpdateRequired As String = "RulesForceUpdateRequired"
Private Const Name_AddErrorsToLog As String = "AddErrorsToLog"
Private Const Name_ConfigLastDateUpdate As String = "ConfigLastDateUpdate"
Private Const Name_ConfigAutoUpdate As String = "ConfigAutoUpdate"
Private Const Name_RulesConfigManualMode As String = "RulesConfigManualMode"
Private Const Name_RulesUpdateConst As String = "RulesUpdateConst"
Private Const Name_RulesReplaceConfig As String = "RulesReplaceConfig"
#End Region
#Region "Declarations"
Private ReadOnly Rules As List(Of DynamicRulesValue)
Friend ReadOnly Property RulesConstants As Dictionary(Of String, String)
#Region "Regex patterns"
Private ReadOnly ReplacePattern_RepoToRaw As RParams
Private ReadOnly ReplacePattern_RawToRepo As RParams
Private ReadOnly ReplacePattern_JsonInfo As RParams
Private ReadOnly ConfigRulesExtract As RParams
#End Region
#Region "Dates"
Private LastUpdateTimeFile As Date = Now.AddYears(-1)
Private LastUpdateTimeRules As Date = Now.AddYears(-1)
#End Region
#Region "Files"
Friend ReadOnly OFScraperConfigPatternFile As SFile = $"{SettingsFolderName}\OFScraperConfigPattern.json"
Friend ReadOnly OFScraperConfigPatternFileConst As SFile = $"{SettingsFolderName}\OFScraperConfigPatternConstants.txt"
Friend ReadOnly Property AuthFile As New SFile($"{SettingsFolderName}\OnlyFans_Auth.json")
Private ReadOnly DynamicRulesFile As SFile
Private ReadOnly DynamicRulesXml As SFile
Private Shared ReadOnly Property DynamicRulesFileImpl As SFile
Get
Return $"{SettingsFolderName}\OnlyFansDynamicRules.txt"
End Get
End Property
Friend Shared Sub ValidateRulesFile()
Dim f As SFile = DynamicRulesFileImpl
If Not f.Exists Then TextSaver.SaveTextToFile(My.Resources.OFResources.DynamicRules, DynamicRulesFileImpl, True)
End Sub
Friend Property ProtectFile As Boolean = False
#End Region
Friend Property UpdateInterval As Integer = UpdateIntervalDefault
Friend Property Mode As Modes = Modes.List
Friend Property PersonalRule As String = String.Empty
Friend Property RulesForceUpdateRequired As Boolean = False
Friend Property RulesUpdateConst As Boolean = True
Friend Property RulesReplaceConfig As Boolean = True
Private ReadOnly Responser As New Responser With {.Accept = "application/json"}
Private ReadOnly RulesLinesComparer As New FComparer(Of String)(Function(x, y) x.StringToLower = y.StringToLower)
Private ReadOnly OFLOG As TextSaver
Private ReadOnly OFError As ErrorsDescriber
Friend Property AddErrorsToLog As Boolean = True
Friend Property NeedToSave As Boolean = False
Private ReadOnly Property ConfigAddress As DynamicRulesValue
Private ReadOnly Property ConfigConstAddress As DynamicRulesValue
Private Property ConfigLastDateUpdate As Date = Now.AddYears(-1)
Friend Property ConfigAutoUpdate As Boolean = True
Friend Property RulesConfigManualMode As Boolean = True
#End Region
#Region "Current, Item, Count"
Private _CurrentRule As DynamicRulesValue
Private _CurrentContainer As EContainer
Private _CurrentContainerRulesText As String = String.Empty
Friend ReadOnly Property CurrentRule As DynamicRulesValue
Get
Return _CurrentRule
End Get
End Property
Friend ReadOnly Property CurrentContainer As EContainer
Get
Return _CurrentContainer
End Get
End Property
Friend ReadOnly Property CurrentContainerRulesText As String
Get
If _CurrentContainerRulesText.IsEmptyString AndAlso AuthFile.Exists Then _
_CurrentContainerRulesText = AuthFile.GetText(OFError).StringTrim
Return _CurrentContainerRulesText
End Get
End Property
Friend ReadOnly Property Exists As Boolean
Get
Return CurrentContainer.ListExists
End Get
End Property
Default Friend ReadOnly Property Item(ByVal Index As Integer) As DynamicRulesValue Implements IMyEnumerator(Of DynamicRulesValue).MyEnumeratorObject
Get
Return Rules(Index)
End Get
End Property
Friend ReadOnly Property Count As Integer Implements IMyEnumerator(Of DynamicRulesValue).MyEnumeratorCount
Get
Return Rules.Count
End Get
End Property
#End Region
#Region "Initializer"
Friend Sub New()
Rules = New List(Of DynamicRulesValue)
DynamicRulesFile = DynamicRulesFileImpl
DynamicRulesXml = DynamicRulesFile
DynamicRulesXml.Extension = "xml"
ReplacePattern_RepoToRaw = New RParams("(.*github.com/([^/]+)/([^/]+)/blob/(.+))", Nothing, 0,
RegexReturn.ReplaceChangeListMatch, EDP.ReturnValue) With {
.PatternReplacement = "https://raw.githubusercontent.com/{2}/{3}/{4}"}
ReplacePattern_JsonInfo = ReplacePattern_RepoToRaw.Copy
ReplacePattern_JsonInfo.PatternReplacement = "https://github.com/{2}/{3}/latest-commit/{4}"
ReplacePattern_RawToRepo = ReplacePattern_RepoToRaw.Copy
ReplacePattern_RawToRepo.Pattern = "(.*raw.githubusercontent.com/([^/]+)/([^/]+)/([^/]+)/(.+))"
ReplacePattern_RawToRepo.PatternReplacement = "https://github.com/{2}/{3}/blob/{4}/{5}"
ConfigRulesExtract = RParams.DMS("DYNAMIC_RULE"":(\{.+?\}[\r\n]+)", 1, RegexOptions.Singleline, EDP.ReturnValue)
OFLOG = New TextSaver($"LOGs\OF_{Now:yyyyMMdd_HHmmss}.txt") With {.LogMode = True, .AutoSave = True, .AutoClear = True}
AddHandler OFLOG.TextSaved, AddressOf OFLOG_TextSaved
OFError = New ErrorsDescriber(EDP.SendToLog + EDP.ReturnValue) With {.DeclaredMessage = New MMessage With {.Loggers = {OFLOG}, .Exists = True}}
Responser.DeclaredError = OFError
Responser.ProcessExceptionDecision =
Function(ByVal Status As IResponserStatus, ByVal NullArg As Object, ByVal CurrentError As ErrorsDescriber) As ErrorsDescriber
If Status.StatusCode = Net.HttpStatusCode.NotFound Then
CurrentError.SendToLogOnlyMessage = True
Dim m As MMessage = CurrentError.DeclaredMessage.Clone
m.Text = $"Nothing found at URL: {Responser.LatestUrlString}"
CurrentError.DeclaredMessage = m
Status.ErrorException = New ErrorsDescriberException(m.Text,,, Status.ErrorException) With {.ReplaceMainMessage = True}
End If
Return CurrentError
End Function
ConfigAddress = ParseURL("https://github.com/AAndyProgram/SCrawler/blob/main/SCrawler/API/OnlyFans/OFScraperConfigPattern.json")
ConfigConstAddress = ParseURL("https://github.com/AAndyProgram/SCrawler/blob/main/SCrawler/API/OnlyFans/OFScraperConfigPatternConstants.txt")
RulesConstants = New Dictionary(Of String, String)
End Sub
#End Region
#Region "Log handlers"
Private _OFLOG_ProcessNotify As Boolean = True
Private Sub OFLOG_TextSaved(sender As Object, e As EventArgs)
If _OFLOG_ProcessNotify And AddErrorsToLog Then _OFLOG_ProcessNotify = False : MyMainLOG = $"The OnlyFans log contains errors: {OFLOG.File}"
End Sub
#End Region
#Region "ParseURL"
Private Const SiteGitHub As String = "github.com"
Private Const SiteGitHubRaw As String = "raw.githubusercontent.com"
Friend Function ParseURL(ByVal URL As String) As DynamicRulesValue
URL = URL.StringTrim
If Not URL.IsEmptyString Then
Dim r As New DynamicRulesValue
Dim rGet As Func(Of String, RParams, String) = Function(__url, pattern) DirectCast(RegexReplace(__url, pattern), IEnumerable(Of String)).FirstOrDefault
If URL.ToLower.Contains(SiteGitHubRaw) Then
r.UrlRaw = URL
r.UrlRepo = rGet(URL, ReplacePattern_RawToRepo)
ElseIf URL.ToLower.Contains(SiteGitHub) Then
r.UrlRepo = URL
r.UrlRaw = rGet(URL, ReplacePattern_RepoToRaw)
End If
If r.Valid Then
r.UpdatedAt = Now.AddYears(-1)
r.UrlLatestCommit = rGet(r.UrlRepo, ReplacePattern_JsonInfo)
r.Exists = True
Return r
End If
End If
Return Nothing
End Function
#End Region
#Region "GetFormat"
Private Shared ReadOnly Property ConfigNodes As String()
Get
Return {"advanced_options", "DYNAMIC_RULE"}
End Get
End Property
Private Const FormatMidPart As String = ":{0}:{1:x}:"
Private ReadOnly FormatExtract As RParams = RParams.DM("(\S+)\s*:\s*\{\s*\d?\s*\}\s*:\s*\{\s*\d?\s*:\s*x\s*\}\s*:\s*(\S+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
Private ReadOnly ContainerStrConv As New CustomProvider(Function(input) If(ACheck(Of Integer)(input), input, $"""{input}"""))
Private ReadOnly ContainerConv As New CustomProvider(Function(ByVal e As Object) As Object
With DirectCast(e, EContainer)
Dim value$ = String.Empty
If .ListExists Then
value = .Select(Function(ee) ee(0).Value).ListToStringE(",", ContainerStrConv, False, String.Empty, EDP.ReturnValue)
If Not value.IsEmptyString Then value = $"[{value}]"
Else
value = AConvert(Of String)(.Value, ContainerStrConv, String.Empty, EDP.SendToLog, EDP.ReturnValue)
End If
If Not value.IsEmptyString Then
value = $"""{ .Name}"": {value}"
Else
value = $"""{ .Name}"": """""
End If
Return value
End With
End Function)
Friend Shared Function GetFormat(ByVal j As EContainer, Optional ByVal Check As Boolean = False,
Optional ByRef CheckResult As Boolean = False,
Optional ByVal TryConfig As Boolean = False, Optional ByRef IsConfig As Boolean = False) As String
Dim pattern$ = String.Empty
With If(TryConfig, j(ConfigNodes), j)
If .ListExists Then
If Not .Value("format").IsEmptyString Then
pattern = .Value("format").Replace("{}", "{0}").Replace("{:x}", "{1:x}")
ElseIf Not .Value("prefix").IsEmptyString And Not .Value("suffix").IsEmptyString Then
pattern = .Value("prefix") & FormatMidPart & .Value("suffix")
ElseIf Not .Value("start").IsEmptyString And Not .Value("end").IsEmptyString Then
pattern = .Value("start") & FormatMidPart & .Value("end")
End If
Dim result As Boolean = Not pattern.IsEmptyString And .Item("checksum_indexes").ListExists And
Not .Value("static_param").IsEmptyString And Not .Value("checksum_constant").IsEmptyString
If Check Then CheckResult = result
If Not result And Not TryConfig Then Return GetFormat(j, Check, CheckResult, True, IsConfig)
End If
End With
Return pattern
End Function
Private Function ConvertAuthText() As String
Dim result$ = String.Empty
With CurrentContainer
If .ListExists Then
Dim f$ = GetFormat(.Self)
If Not f.IsEmptyString Then
Dim l As List(Of String) = RegexReplace(f, FormatExtract)
If l.ListExists(3) Then
Dim s$ = l(1), e$ = l(2)
.Value("format") = s & FormatMidPart & e
.Value("prefix") = s
.Value("suffix") = e
.Value("start") = s
.Value("end") = e
Dim t$ = .ListToStringE(",", ContainerConv, False)
If Not t.IsEmptyString Then t = "{" & t & "}"
Return t
End If
End If
End If
End With
Return String.Empty
End Function
#End Region
#Region "Load, Save"
Private Function GetTextLines(ByVal Input As String) As List(Of String)
If Not Input.IsEmptyString Then
Return ListAddList(Nothing, Input.StringTrim.Split(vbLf), LAP.NotContainsOnly, EDP.ReturnValue,
CType(Function(inp$) inp.StringTrim, Func(Of Object, Object)))
Else
Return New List(Of String)
End If
End Function
Private Sub ParseConsts(ByVal Source As String)
If Not Source.IsEmptyString Then
Dim l As List(Of String) = GetTextLines(Source)
Dim v$()
If l.ListExists Then
RulesConstants.Clear()
For Each value$ In l
If Not value.IsEmptyString Then
v = value.Split("=")
If v.ListExists(2) Then RulesConstants.Add(v(0), v(1))
End If
Next
End If
End If
End Sub
Private Const RulesNode As String = "Rules"
Private _InitialValuesLoaded As Boolean = False
Private Sub LoadInitialValues()
If Not _InitialValuesLoaded Then
_InitialValuesLoaded = True
If Not OFScraperConfigPatternFile.Exists Then
Dim t$ = Text.Encoding.UTF8.GetString(My.Resources.OFResources.OFScraperConfigPattern)
TextSaver.SaveTextToFile(t, OFScraperConfigPatternFile, True)
End If
If Not OFScraperConfigPatternFileConst.Exists Then _
TextSaver.SaveTextToFile(My.Resources.OFResources.OFScraperConfigPatternConstants, OFScraperConfigPatternFileConst, True)
If OFScraperConfigPatternFileConst.Exists Then ParseConsts(OFScraperConfigPatternFileConst.GetText(OFError))
If DynamicRulesXml.Exists Then
Rules.Clear()
Using x As New XmlFile(DynamicRulesXml, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True}
x.LoadData(OFError)
Dim dNull As Date = Now.AddYears(-1)
LastUpdateTimeFile = x.Value(Name_LastUpdateTimeFile).ToDateDef(dNull)
LastUpdateTimeRules = x.Value(Name_LastUpdateTimeRules).ToDateDef(dNull)
ProtectFile = x.Value(Name_ProtectFile).FromXML(Of Boolean)(False)
Mode = x.Value(Name_Mode).FromXML(Of Integer)(Modes.List)
UpdateInterval = x.Value(Name_UpdateInterval).FromXML(Of Integer)(UpdateIntervalDefault)
PersonalRule = x.Value(Name_PersonalRule)
RulesForceUpdateRequired = x.Value(Name_RulesForceUpdateRequired).FromXML(Of Boolean)(False)
RulesUpdateConst = x.Value(Name_RulesUpdateConst).FromXML(Of Boolean)(True)
RulesReplaceConfig = x.Value(Name_RulesReplaceConfig).FromXML(Of Boolean)(True)
AddErrorsToLog = x.Value(Name_AddErrorsToLog).FromXML(Of Boolean)(False)
ConfigAutoUpdate = x.Value(Name_ConfigAutoUpdate).FromXML(Of Boolean)(True)
RulesConfigManualMode = x.Value(Name_RulesConfigManualMode).FromXML(Of Boolean)(True)
ConfigLastDateUpdate = x.Value(Name_ConfigLastDateUpdate).ToDateDef(Now.AddYears(-1))
If x.Contains(RulesNode) Then Rules.ListAddList(x({RulesNode}), LAP.IgnoreICopier, OFError)
End Using
End If
End If
End Sub
Friend Sub Save()
Using x As New XmlFile With {.AllowSameNames = True, .Name = "DynamicRules"}
x.Add(Name_LastUpdateTimeFile, LastUpdateTimeFile.ToStringDateDef)
x.Add(Name_LastUpdateTimeRules, LastUpdateTimeRules.ToStringDateDef)
x.Add(Name_ProtectFile, ProtectFile.BoolToInteger)
x.Add(Name_Mode, CInt(Mode))
x.Add(Name_UpdateInterval, UpdateInterval)
x.Add(Name_PersonalRule, PersonalRule)
x.Add(Name_RulesForceUpdateRequired, RulesForceUpdateRequired.BoolToInteger)
x.Add(Name_RulesUpdateConst, RulesUpdateConst.BoolToInteger)
x.Add(Name_RulesReplaceConfig, RulesReplaceConfig.BoolToInteger)
x.Add(Name_AddErrorsToLog, AddErrorsToLog.BoolToInteger)
x.Add(Name_ConfigAutoUpdate, ConfigAutoUpdate.BoolToInteger)
x.Add(Name_RulesConfigManualMode, RulesConfigManualMode.BoolToInteger)
x.Add(Name_ConfigLastDateUpdate, ConfigLastDateUpdate.ToStringDateDef)
If Count > 0 Then
Rules.Sort()
x.Add(New EContainer(RulesNode))
x.Last.AddRange(Rules)
End If
x.Save(DynamicRulesXml, OFError)
End Using
If Count > 0 Then
Using t As New TextSaver(DynamicRulesFile)
Rules.ForEach(Sub(r) If Not r.UrlRepo.IsEmptyString Then t.AppendLine(r.UrlRepo))
t.Save(OFError)
End Using
End If
End Sub
#End Region
#Region "Update"
Private _UpdateInProgress As Boolean = False
Private _ForcedUpdate As Boolean = False
Friend Function Update(ByVal Force As Boolean, Optional ByVal LoadListOnly As Boolean = False) As Boolean
Dim skip As Boolean = _UpdateInProgress
If skip And _ForcedUpdate Then Force = False
_ForcedUpdate = Force
While _UpdateInProgress : Threading.Thread.Sleep(200) : End While
If Not skip Or Force Then UpdateImpl(Force Or RulesForceUpdateRequired, LoadListOnly)
Return Exists
End Function
Private Sub UpdateImpl(ByVal Force As Boolean, Optional ByVal LoadListOnly As Boolean = False)
Try
If Not _UpdateInProgress Then
_UpdateInProgress = True
LoadInitialValues()
Dim r$
Dim process As Boolean = False, updated As Boolean = False
Dim forceSave As Boolean = RulesForceUpdateRequired Or Not DynamicRulesFile.Exists Or Not DynamicRulesXml.Exists
Dim textLocal As List(Of String)
Dim i%
Dim rule As DynamicRulesValue
Dim e As EContainer
Dim errDate As Date = Now.AddYears(-1)
Dim d As Date?
'2024-06-12T12:44:06.000-05:00
Dim dateProvider As New ADateTime("yyyy-MM-ddTHH:mm:ss.fff%K")
RulesForceUpdateRequired = False
If Not DynamicRulesFile.Exists Then process = True : ValidateRulesFile()
'update rules list
If Not LoadListOnly And (LastUpdateTimeFile.AddMinutes(UpdateInterval) < Now Or process Or Force) Then
LastUpdateTimeFile = Now
r = Responser.GetResponse("https://raw.githubusercontent.com/AAndyProgram/SCrawler/main/SCrawler/API/OnlyFans/DynamicRules.txt")
If Not r.IsEmptyString Then
Dim textWeb As List(Of String) = GetTextLines(r)
Dim fileText$
If textWeb.ListExists Then
Using t As New TextSaver(DynamicRulesFile)
If ProtectFile Then
fileText = DynamicRulesFile.GetText(OFError)
t.Append(fileText)
textLocal = GetTextLines(fileText)
If textLocal.ListExists Then _
textLocal.ForEach(Sub(tt) If Not tt.IsEmptyString AndAlso Not textWeb.Contains(tt, RulesLinesComparer) Then _
t.AppendLine(tt) : updated = True) : textLocal.Clear()
Else
t.Append(r)
updated = True
End If
t.Save(OFError)
End Using
textWeb.Clear()
End If
End If
End If
'update config and consts
If Not LoadListOnly AndAlso ConfigAutoUpdate AndAlso ConfigLastDateUpdate.AddMinutes(UpdateInterval) < Now Then
Dim __upConf As Boolean = False
Dim __dConf As Date = ConfigLastDateUpdate
Dim parseConfigFiles As Action(Of DynamicRulesValue, SFile, Boolean) =
Sub(ByVal __rule As DynamicRulesValue, ByVal __fileSave As SFile, ByVal isConstFile As Boolean)
r = Responser.GetResponse(__rule.UrlLatestCommit)
If Not r.IsEmptyString Then
e = JsonDocument.Parse(r, OFError)
If e.ListExists Then
d = AConvert(Of Date)(e.Value("date"), dateProvider, Nothing)
Dim dConf As Date = If(d, errDate)
If dConf > __dConf Then
__dConf = dConf
__upConf = True
updated = True
r = Responser.GetResponse(__rule.UrlRaw)
If Not r.IsEmptyString Then
TextSaver.SaveTextToFile(r, __fileSave, True, False, OFError)
If isConstFile Then ParseConsts(r)
End If
End If
e.Dispose()
End If
End If
End Sub
'Update consts
If RulesUpdateConst Then parseConfigFiles(ConfigConstAddress, OFScraperConfigPatternFileConst, True)
'Update config
parseConfigFiles(ConfigAddress, OFScraperConfigPatternFile, False)
If __upConf Then ConfigLastDateUpdate = Now
End If
'generate rules, update rules dates
If LastUpdateTimeRules.AddMinutes(UpdateInterval) < Now Or updated Or Force Or LoadListOnly Then
process = True
If Mode = Modes.Personal And Not PersonalRule.IsEmptyString Then
If Not LoadListOnly Then LastUpdateTimeRules = Now : updated = True
Else
If Not LoadListOnly Then LastUpdateTimeRules = Now : updated = True
textLocal = GetTextLines(DynamicRulesFile.GetText(OFError))
If textLocal.ListExists Then
If Not LoadListOnly And Count > 0 Then
For i = 0 To Count - 1
rule = Rules(i)
rule.Exists = False
Rules(i) = rule
Next
End If
For Each url$ In textLocal
url = url.StringTrim
If Not url.IsEmptyString Then
i = IndexOf(url)
If i >= 0 Then
rule = Rules(i)
Else
rule = ParseURL(url)
If rule.Valid Then
i = Add(rule, False, False)
Else
rule = Nothing
End If
End If
If Not LoadListOnly Then
If i >= 0 And rule.Valid And Not rule.UrlLatestCommit.IsEmptyString Then
rule.Exists = True
r = Responser.GetResponse(rule.UrlLatestCommit)
If Not r.IsEmptyString Then
e = JsonDocument.Parse(r, OFError)
If e.ListExists Then
d = AConvert(Of Date)(e.Value("date"), dateProvider, Nothing)
rule.UpdatedAt = If(d, errDate)
e.Dispose()
Else
rule.Broken = True
End If
Else
rule.Broken = True
End If
Rules(i) = rule
End If
If Rules.RemoveAll(Function(rr) Not rr.Exists) > 0 Then updated = True
End If
End If
Next
End If
End If
End If
If Count > 0 Then Rules.Sort()
'download and load the rule
If (LoadListOnly And AuthFile.Exists) Or (Not LoadListOnly And ((updated And Count > 0) Or Not AuthFile.Exists)) Then
_CurrentRule = Nothing
_CurrentContainer.DisposeIfReady
_CurrentContainer = Nothing
Dim processRule As Func(Of DynamicRulesValue, Boolean, DialogResult) =
Function(ByVal __rule As DynamicRulesValue, ByVal reparseAuth As Boolean) As DialogResult
Dim fromAuthFile As Boolean = (LoadListOnly Or reparseAuth) AndAlso AuthFile.Exists
If fromAuthFile Then
r = AuthFile.GetText(OFError)
Else
r = GetWebString(__rule.UrlRaw,, OFError)
End If
Dim j As EContainer = JsonDocument.Parse(r, OFError)
Dim checkResult As Boolean = False
Dim isConfig As Boolean = False
Dim textToSave As String = r
If j.ListExists AndAlso Not GetFormat(j, True, checkResult,, isConfig).IsEmptyString AndAlso checkResult Then
If isConfig Then textToSave = RegexReplace(r, ConfigRulesExtract)
If textToSave.IsEmptyString Then
Return DialogResult.Retry
Else
_CurrentRule = __rule
_CurrentContainer = If(isConfig, j(ConfigNodes), j)
textToSave = ConvertAuthText()
_CurrentContainerRulesText = textToSave
If (Not fromAuthFile Or Not textToSave.StringTrim = r.StringTrim) And Not textToSave.IsEmptyString Then
TextSaver.SaveTextToFile(textToSave, AuthFile, True, False, OFError)
If Not reparseAuth Then processRule(__rule, True)
End If
Return DialogResult.OK
End If
End If
Return DialogResult.No
End Function
If Mode = Modes.Personal And Not PersonalRule.IsEmptyString Then
processRule(New DynamicRulesValue With {.UrlRepo = PersonalRule, .UrlRaw = PersonalRule}, False)
Else
For Each rule In Rules
If rule.Valid And Not rule.Broken Then
Select Case processRule(rule, False)
Case DialogResult.Retry : Continue For
Case DialogResult.OK : Exit For
End Select
End If
Next
End If
End If
If updated Or forceSave Then Save()
_UpdateInProgress = False
End If
Catch ex As Exception
ErrorsDescriber.Execute(OFError, ex, "[OnlyFans.DynamicRulesEnv.UpdateImpl]")
_UpdateInProgress = False
End Try
End Sub
#End Region
#Region "Add, IndexOf"
Friend Function Add(ByVal Rule As DynamicRulesValue, Optional ByVal AutoSort As Boolean = True, Optional ByVal AutoSave As Boolean = False) As Integer
If Rule.Valid Then
Dim i% = IndexOf(Rule)
If i = -1 Then
Rules.Add(Rule)
i = Count - 1
If AutoSort Then Rules.Sort() : i = IndexOf(Rule)
If AutoSave Then Save()
End If
Return i
Else
Return -1
End If
End Function
Friend Function RemoveAt(ByVal Index As Integer) As Boolean
If Index.ValueBetween(0, Count - 1) Then
Rules.RemoveAt(Index)
Return True
Else
Return False
End If
End Function
Friend Function IndexOf(ByVal URL As String) As Integer
If Count > 0 Then
URL = URL.StringToLower.Trim
Return Rules.FindIndex(Function(r) r.UrlRepo.StringToLower = URL Or r.UrlRaw.StringToLower = URL Or r.UrlLatestCommit.StringToLower = URL)
Else
Return -1
End If
End Function
#End Region
#Region "ICopier Support"
Friend Overloads Function Copy() As Object Implements ICopier.Copy
Return (New DynamicRulesEnv).Copy(Me)
End Function
Friend Overloads Function Copy(ByVal Source As Object) As Object Implements ICopier.Copy
Return Copy(Source, False)
End Function
Friend Overloads Function Copy(ByVal Source As Object, ByVal UpdateForceProperty As Boolean) As Object
If Not Source Is Nothing Then
With DirectCast(Source, DynamicRulesEnv)
If Not RulesForceUpdateRequired And UpdateForceProperty Then _
RulesForceUpdateRequired = Not Rules.ListEquals(.Rules) Or Not Mode = .Mode Or
(.Mode = Modes.Personal And Not PersonalRule = .PersonalRule)
ProtectFile = .ProtectFile
Mode = .Mode
UpdateInterval = .UpdateInterval
PersonalRule = .PersonalRule
If Not RulesForceUpdateRequired Then RulesForceUpdateRequired = .RulesForceUpdateRequired
RulesUpdateConst = .RulesUpdateConst
RulesReplaceConfig = .RulesReplaceConfig
AddErrorsToLog = .AddErrorsToLog
ConfigAutoUpdate = .ConfigAutoUpdate
RulesConfigManualMode = .RulesConfigManualMode
Rules.Clear()
If .Count > 0 Then Rules.AddRange(.Rules)
End With
Return Me
Else
Return Nothing
End If
End Function
#End Region
#Region "IEnumerable Support"
Private Function GetEnumerator() As IEnumerator(Of DynamicRulesValue) Implements IEnumerable(Of DynamicRulesValue).GetEnumerator
Return New MyEnumerator(Of DynamicRulesValue)(Me)
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
#End Region
#Region "IDisposable Support"
Private disposedValue As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue Then
If disposing Then
Rules.Clear()
_CurrentContainer.DisposeIfReady
Responser.DisposeIfReady
End If
_CurrentContainer = Nothing
disposedValue = True
End If
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
Friend Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
End Namespace

View File

@@ -64,6 +64,20 @@ Namespace My.Resources
End Set End Set
End Property End Property
'''<summary>
''' Looks up a localized string similar to https://github.com/datawhores/onlyfans-dynamic-rules/blob/main/dynamicRules.json
'''https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/main/dynamicRules.json
'''https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/patch-1/dynamicRules.json
'''https://github.com/DATAHOARDERS/dynamic-rules/blob/main/onlyfans.json
'''https://github.com/DIGITALCRIMINAL/dynamic-rules/blob/main/onlyfans.json
'''https://github.com/deviint/onlyfans-dynamic-rules/blob/main/dynamicRules.json.
'''</summary>
Friend Shared ReadOnly Property DynamicRules() As String
Get
Return ResourceManager.GetString("DynamicRules", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Looks up a localized resource of type System.Byte[]. ''' Looks up a localized resource of type System.Byte[].
'''</summary> '''</summary>
@@ -73,5 +87,15 @@ Namespace My.Resources
Return CType(obj,Byte()) Return CType(obj,Byte())
End Get End Get
End Property End Property
'''<summary>
''' Looks up a localized string similar to dynamic-mode-default=generic
'''RULE_VALUE=DYNAMIC_GENERIC_URL.
'''</summary>
Friend Shared ReadOnly Property OFScraperConfigPatternConstants() As String
Get
Return ResourceManager.GetString("OFScraperConfigPatternConstants", resourceCulture)
End Get
End Property
End Class End Class
End Namespace End Namespace

View File

@@ -118,7 +118,13 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="DynamicRules" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>DynamicRules.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="OFScraperConfigPattern" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="OFScraperConfigPattern" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>OFScraperConfigPattern.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>OFScraperConfigPattern.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="OFScraperConfigPatternConstants" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>OFScraperConfigPatternConstants.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root> </root>

View File

@@ -1,65 +1,63 @@
{ {
"config": { "main_profile": "main_profile",
"main_profile": "main_profile", "metadata": "{configpath}/{profile}/.data/{model_username}_{model_id}",
"metadata": "{configpath}/{profile}/.data/{model_username}_{model_id}", "discord": "",
"discord": "", "file_options": {
"file_options": { "save_location": "",
"save_location": "", "dir_format": "",
"dir_format": "", "file_format": "{filename}.{ext}",
"file_format": "{filename}.{ext}", "textlength": 0,
"textlength": 0, "space_replacer": " ",
"space-replacer": " ", "date": "YYYY-MM-DD"
"date": "YYYY-MM-DD" },
}, "download_options": {
"download_options": { "file_size_max": 0,
"file_size_limit": 0, "file_size_min": 0,
"file_size_min": 0, "filter": [
"filter": [ "Images",
"Images", "Audios",
"Audios", "Videos"
"Videos" ],
], "auto_resume": false
"auto_resume": false },
}, "binary_options": {
"binary_options": { "mp4decrypt": "",
"mp4decrypt": "", "ffmpeg": ""
"ffmpeg": "" },
}, "cdm_options": {
"cdm_options": { "private-key": null,
"private-key": null, "client-id": null,
"client-id": null, "key-mode-default": "cdrm",
"key-mode-default": "cdrm", "keydb_api": ""
"keydb_api": "" },
}, "performance_options": {
"performance_options": { "download-sems": 6,
"download-sems": 6, "maxfile-sem": 0,
"maxfile-sem": 0, "threads": 5
"threads": 5 },
}, "advanced_options": {
"advanced_options": { "code-execution": false,
"code-execution": false, "dynamic-mode-default": "generic",
"dynamic-mode-default": "sneaky", "backend": "aio",
"backend": "aio", "downloadbars": false,
"downloadbars": false, "cache-mode": "sqlite",
"cache-mode": "sqlite", "appendlog": true,
"appendlog": true, "custom": null,
"custom": null, "sanitize_text": false,
"sanitize_text": false, "avatar": true,
"avatar": true, "custom_values": {
"custom_values": { "DYNAMIC_GENERIC_URL": "https://raw.githubusercontent.com/datawhores/onlyfans-dynamic-rules/main/dynamicRules.json",
"SNEAKY": "https://raw.githubusercontent.com/Growik/onlyfans-dynamic-rules/main/rules.json", "CDRM": "https://old.cdrm-project.com/wv"
"CDRM": "https://old.cdrm-project.com/wv"
}
},
"responsetype": {
"timeline": "Posts",
"message": "Messages",
"archived": "Archived",
"paid": "Messages",
"stories": "Stories",
"highlights": "Stories",
"profile": "Profile",
"pinned": "Posts"
} }
},
"responsetype": {
"timeline": "Posts",
"message": "Messages",
"archived": "Archived",
"paid": "Messages",
"stories": "Stories",
"highlights": "Stories",
"profile": "Profile",
"pinned": "Posts"
} }
} }

View File

@@ -0,0 +1,2 @@
dynamic-mode-default=generic
RULE_VALUE=DYNAMIC_GENERIC_URL

View File

@@ -0,0 +1,361 @@
' Copyright (C) Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.OnlyFans
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class OnlyFansAdvancedSettingsForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(OnlyFansAdvancedSettingsForm))
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 TP_RULES_LIST As System.Windows.Forms.TableLayoutPanel
Dim TP_RULES_LIST_LEFT As System.Windows.Forms.TableLayoutPanel
Dim TT_MAIN As System.Windows.Forms.ToolTip
Me.TXT_UP_INTERVAL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_PERSONAL_RULE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CONTAINER_LIST = New System.Windows.Forms.ToolStripContainer()
Me.LIST_RULES = New System.Windows.Forms.ListBox()
Me.OPT_RULES_LIST = New System.Windows.Forms.RadioButton()
Me.CH_PROTECTED = New System.Windows.Forms.CheckBox()
Me.CH_FORCE_UPDATE = New System.Windows.Forms.CheckBox()
Me.CH_LOG_ERR = New System.Windows.Forms.CheckBox()
Me.CH_RULES_REPLACE_CONFIG = New System.Windows.Forms.CheckBox()
Me.CH_UPDATE_CONF = New System.Windows.Forms.CheckBox()
Me.CH_UPDATE_RULES_CONST = New System.Windows.Forms.CheckBox()
Me.CH_CONFIG_MANUAL_MODE = New System.Windows.Forms.CheckBox()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_RULES_LIST = New System.Windows.Forms.TableLayoutPanel()
TP_RULES_LIST_LEFT = New System.Windows.Forms.TableLayoutPanel()
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
TP_MAIN.SuspendLayout()
CType(Me.TXT_UP_INTERVAL, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_PERSONAL_RULE, System.ComponentModel.ISupportInitialize).BeginInit()
TP_RULES_LIST.SuspendLayout()
Me.CONTAINER_LIST.ContentPanel.SuspendLayout()
Me.CONTAINER_LIST.SuspendLayout()
TP_RULES_LIST_LEFT.SuspendLayout()
Me.SuspendLayout()
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(464, 341)
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(464, 341)
CONTAINER_MAIN.TabIndex = 1
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.TXT_UP_INTERVAL, 0, 5)
TP_MAIN.Controls.Add(Me.TXT_PERSONAL_RULE, 0, 6)
TP_MAIN.Controls.Add(TP_RULES_LIST, 0, 7)
TP_MAIN.Controls.Add(Me.CH_LOG_ERR, 0, 0)
TP_MAIN.Controls.Add(Me.CH_RULES_REPLACE_CONFIG, 0, 1)
TP_MAIN.Controls.Add(Me.CH_UPDATE_CONF, 0, 4)
TP_MAIN.Controls.Add(Me.CH_UPDATE_RULES_CONST, 0, 2)
TP_MAIN.Controls.Add(Me.CH_CONFIG_MANUAL_MODE, 0, 3)
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 = 8
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Size = New System.Drawing.Size(464, 341)
TP_MAIN.TabIndex = 0
'
'TXT_UP_INTERVAL
'
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Name = "Refresh"
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Name = "Clear"
ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_UP_INTERVAL.Buttons.Add(ActionButton7)
Me.TXT_UP_INTERVAL.Buttons.Add(ActionButton8)
Me.TXT_UP_INTERVAL.CaptionText = "Dynamic rules update"
Me.TXT_UP_INTERVAL.CaptionToolTipEnabled = True
Me.TXT_UP_INTERVAL.CaptionToolTipText = "'Dynamic rules' update interval (minutes). Default: 1440"
Me.TXT_UP_INTERVAL.CaptionWidth = 120.0R
Me.TXT_UP_INTERVAL.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_UP_INTERVAL.Location = New System.Drawing.Point(4, 134)
Me.TXT_UP_INTERVAL.Name = "TXT_UP_INTERVAL"
Me.TXT_UP_INTERVAL.Size = New System.Drawing.Size(456, 22)
Me.TXT_UP_INTERVAL.TabIndex = 5
'
'TXT_PERSONAL_RULE
'
Me.TXT_PERSONAL_RULE.AutoShowClearButton = True
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
ActionButton9.Enabled = False
ActionButton9.Name = "Clear"
ActionButton9.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton9.Visible = False
Me.TXT_PERSONAL_RULE.Buttons.Add(ActionButton9)
Me.TXT_PERSONAL_RULE.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.RadioButton
Me.TXT_PERSONAL_RULE.CaptionText = "Dynamic rules URL"
Me.TXT_PERSONAL_RULE.CaptionToolTipEnabled = True
Me.TXT_PERSONAL_RULE.CaptionToolTipText = "Overwrite 'Dynamic rules' with this URL." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Change this value only if you know what" &
" you are doing."
Me.TXT_PERSONAL_RULE.CaptionWidth = 120.0R
Me.TXT_PERSONAL_RULE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_PERSONAL_RULE.LeaveDefaultButtons = True
Me.TXT_PERSONAL_RULE.Location = New System.Drawing.Point(4, 163)
Me.TXT_PERSONAL_RULE.Name = "TXT_PERSONAL_RULE"
Me.TXT_PERSONAL_RULE.Size = New System.Drawing.Size(456, 22)
Me.TXT_PERSONAL_RULE.TabIndex = 6
'
'TP_RULES_LIST
'
TP_RULES_LIST.ColumnCount = 2
TP_RULES_LIST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120.0!))
TP_RULES_LIST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_RULES_LIST.Controls.Add(Me.CONTAINER_LIST, 1, 0)
TP_RULES_LIST.Controls.Add(TP_RULES_LIST_LEFT, 0, 0)
TP_RULES_LIST.Dock = System.Windows.Forms.DockStyle.Fill
TP_RULES_LIST.Location = New System.Drawing.Point(4, 192)
TP_RULES_LIST.Name = "TP_RULES_LIST"
TP_RULES_LIST.RowCount = 1
TP_RULES_LIST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_RULES_LIST.Size = New System.Drawing.Size(456, 145)
TP_RULES_LIST.TabIndex = 7
'
'CONTAINER_LIST
'
Me.CONTAINER_LIST.BottomToolStripPanelVisible = False
'
'CONTAINER_LIST.ContentPanel
'
Me.CONTAINER_LIST.ContentPanel.Controls.Add(Me.LIST_RULES)
Me.CONTAINER_LIST.ContentPanel.Size = New System.Drawing.Size(330, 114)
Me.CONTAINER_LIST.Dock = System.Windows.Forms.DockStyle.Fill
Me.CONTAINER_LIST.LeftToolStripPanelVisible = False
Me.CONTAINER_LIST.Location = New System.Drawing.Point(123, 3)
Me.CONTAINER_LIST.Name = "CONTAINER_LIST"
Me.CONTAINER_LIST.RightToolStripPanelVisible = False
Me.CONTAINER_LIST.Size = New System.Drawing.Size(330, 139)
Me.CONTAINER_LIST.TabIndex = 1
'
'LIST_RULES
'
Me.LIST_RULES.Dock = System.Windows.Forms.DockStyle.Fill
Me.LIST_RULES.FormattingEnabled = True
Me.LIST_RULES.Location = New System.Drawing.Point(0, 0)
Me.LIST_RULES.Name = "LIST_RULES"
Me.LIST_RULES.Size = New System.Drawing.Size(330, 114)
Me.LIST_RULES.TabIndex = 0
'
'TP_RULES_LIST_LEFT
'
TP_RULES_LIST_LEFT.ColumnCount = 1
TP_RULES_LIST_LEFT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_RULES_LIST_LEFT.Controls.Add(Me.OPT_RULES_LIST, 0, 0)
TP_RULES_LIST_LEFT.Controls.Add(Me.CH_PROTECTED, 0, 1)
TP_RULES_LIST_LEFT.Controls.Add(Me.CH_FORCE_UPDATE, 0, 2)
TP_RULES_LIST_LEFT.Dock = System.Windows.Forms.DockStyle.Fill
TP_RULES_LIST_LEFT.Location = New System.Drawing.Point(0, 0)
TP_RULES_LIST_LEFT.Margin = New System.Windows.Forms.Padding(0)
TP_RULES_LIST_LEFT.Name = "TP_RULES_LIST_LEFT"
TP_RULES_LIST_LEFT.RowCount = 4
TP_RULES_LIST_LEFT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_RULES_LIST_LEFT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_RULES_LIST_LEFT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_RULES_LIST_LEFT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_RULES_LIST_LEFT.Size = New System.Drawing.Size(120, 145)
TP_RULES_LIST_LEFT.TabIndex = 0
'
'OPT_RULES_LIST
'
Me.OPT_RULES_LIST.AutoSize = True
Me.OPT_RULES_LIST.CheckAlign = System.Drawing.ContentAlignment.MiddleRight
Me.OPT_RULES_LIST.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_RULES_LIST.Location = New System.Drawing.Point(3, 3)
Me.OPT_RULES_LIST.Margin = New System.Windows.Forms.Padding(3, 3, 0, 3)
Me.OPT_RULES_LIST.Name = "OPT_RULES_LIST"
Me.OPT_RULES_LIST.Size = New System.Drawing.Size(117, 19)
Me.OPT_RULES_LIST.TabIndex = 0
Me.OPT_RULES_LIST.TabStop = True
Me.OPT_RULES_LIST.Text = "Dynamic rules list"
Me.OPT_RULES_LIST.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(Me.OPT_RULES_LIST, "List of dynamic rules sources." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "If selected, the most recently updated source wil" &
"l be selected.")
Me.OPT_RULES_LIST.UseVisualStyleBackColor = True
'
'CH_PROTECTED
'
Me.CH_PROTECTED.AutoSize = True
Me.CH_PROTECTED.CheckAlign = System.Drawing.ContentAlignment.MiddleRight
Me.CH_PROTECTED.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_PROTECTED.Location = New System.Drawing.Point(3, 28)
Me.CH_PROTECTED.Margin = New System.Windows.Forms.Padding(3, 3, 0, 3)
Me.CH_PROTECTED.Name = "CH_PROTECTED"
Me.CH_PROTECTED.Size = New System.Drawing.Size(117, 19)
Me.CH_PROTECTED.TabIndex = 1
Me.CH_PROTECTED.Text = "Protected list"
Me.CH_PROTECTED.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(Me.CH_PROTECTED, "If checked, the new source will be added, but the rules list will not be overwrit" &
"ten by the updated one.")
Me.CH_PROTECTED.UseVisualStyleBackColor = True
'
'CH_FORCE_UPDATE
'
Me.CH_FORCE_UPDATE.AutoSize = True
Me.CH_FORCE_UPDATE.CheckAlign = System.Drawing.ContentAlignment.MiddleRight
Me.CH_FORCE_UPDATE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FORCE_UPDATE.Location = New System.Drawing.Point(3, 53)
Me.CH_FORCE_UPDATE.Margin = New System.Windows.Forms.Padding(3, 3, 0, 3)
Me.CH_FORCE_UPDATE.Name = "CH_FORCE_UPDATE"
Me.CH_FORCE_UPDATE.Size = New System.Drawing.Size(117, 19)
Me.CH_FORCE_UPDATE.TabIndex = 2
Me.CH_FORCE_UPDATE.Text = "Force update"
Me.CH_FORCE_UPDATE.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(Me.CH_FORCE_UPDATE, "Check this if you want to force the rules to update.")
Me.CH_FORCE_UPDATE.UseVisualStyleBackColor = True
'
'CH_LOG_ERR
'
Me.CH_LOG_ERR.AutoSize = True
Me.CH_LOG_ERR.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_LOG_ERR.Location = New System.Drawing.Point(4, 4)
Me.CH_LOG_ERR.Name = "CH_LOG_ERR"
Me.CH_LOG_ERR.Size = New System.Drawing.Size(456, 19)
Me.CH_LOG_ERR.TabIndex = 0
Me.CH_LOG_ERR.Text = "Add dynamic rules errors to the log"
TT_MAIN.SetToolTip(Me.CH_LOG_ERR, "OnlyFans errors will be added to a separate log." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "A checked checkbox means that e" &
"rror notification will be added to the main log.")
Me.CH_LOG_ERR.UseVisualStyleBackColor = True
'
'CH_RULES_REPLACE_CONFIG
'
Me.CH_RULES_REPLACE_CONFIG.AutoSize = True
Me.CH_RULES_REPLACE_CONFIG.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_RULES_REPLACE_CONFIG.Location = New System.Drawing.Point(4, 30)
Me.CH_RULES_REPLACE_CONFIG.Name = "CH_RULES_REPLACE_CONFIG"
Me.CH_RULES_REPLACE_CONFIG.Size = New System.Drawing.Size(456, 19)
Me.CH_RULES_REPLACE_CONFIG.TabIndex = 1
Me.CH_RULES_REPLACE_CONFIG.Text = "Replace rules in OF-Scraper configuration file"
TT_MAIN.SetToolTip(Me.CH_RULES_REPLACE_CONFIG, "If checked, the dynamic rules (in the config) will be replaced with actual values" &
".")
Me.CH_RULES_REPLACE_CONFIG.UseVisualStyleBackColor = True
'
'CH_UPDATE_CONF
'
Me.CH_UPDATE_CONF.AutoSize = True
Me.CH_UPDATE_CONF.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_UPDATE_CONF.Location = New System.Drawing.Point(4, 108)
Me.CH_UPDATE_CONF.Name = "CH_UPDATE_CONF"
Me.CH_UPDATE_CONF.Size = New System.Drawing.Size(456, 19)
Me.CH_UPDATE_CONF.TabIndex = 4
Me.CH_UPDATE_CONF.Text = "Update configuration file during update"
TT_MAIN.SetToolTip(Me.CH_UPDATE_CONF, "Update the configuration pattern from the site during update.")
Me.CH_UPDATE_CONF.UseVisualStyleBackColor = True
'
'CH_UPDATE_RULES_CONST
'
Me.CH_UPDATE_RULES_CONST.AutoSize = True
Me.CH_UPDATE_RULES_CONST.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_UPDATE_RULES_CONST.Location = New System.Drawing.Point(4, 56)
Me.CH_UPDATE_RULES_CONST.Name = "CH_UPDATE_RULES_CONST"
Me.CH_UPDATE_RULES_CONST.Size = New System.Drawing.Size(456, 19)
Me.CH_UPDATE_RULES_CONST.TabIndex = 2
Me.CH_UPDATE_RULES_CONST.Text = "Update rules constants file during update"
TT_MAIN.SetToolTip(Me.CH_UPDATE_RULES_CONST, "Update rules constants from the site during update")
Me.CH_UPDATE_RULES_CONST.UseVisualStyleBackColor = True
'
'CH_CONFIG_MANUAL_MODE
'
Me.CH_CONFIG_MANUAL_MODE.AutoSize = True
Me.CH_CONFIG_MANUAL_MODE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_CONFIG_MANUAL_MODE.Location = New System.Drawing.Point(4, 82)
Me.CH_CONFIG_MANUAL_MODE.Name = "CH_CONFIG_MANUAL_MODE"
Me.CH_CONFIG_MANUAL_MODE.Size = New System.Drawing.Size(456, 19)
Me.CH_CONFIG_MANUAL_MODE.TabIndex = 3
Me.CH_CONFIG_MANUAL_MODE.Text = "Dynamic rules 'Manual' mode"
TT_MAIN.SetToolTip(Me.CH_CONFIG_MANUAL_MODE, "The rules will be added to the config as is, without using a link.")
Me.CH_CONFIG_MANUAL_MODE.UseVisualStyleBackColor = True
'
'OnlyFansAdvancedSettingsForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(464, 341)
Me.Controls.Add(CONTAINER_MAIN)
Me.Icon = Global.SCrawler.My.Resources.SiteResources.OnlyFansIcon_32
Me.KeyPreview = True
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(480, 380)
Me.Name = "OnlyFansAdvancedSettingsForm"
Me.ShowInTaskbar = False
Me.Text = "Settings"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
TP_MAIN.ResumeLayout(False)
TP_MAIN.PerformLayout()
CType(Me.TXT_UP_INTERVAL, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_PERSONAL_RULE, System.ComponentModel.ISupportInitialize).EndInit()
TP_RULES_LIST.ResumeLayout(False)
Me.CONTAINER_LIST.ContentPanel.ResumeLayout(False)
Me.CONTAINER_LIST.ResumeLayout(False)
Me.CONTAINER_LIST.PerformLayout()
TP_RULES_LIST_LEFT.ResumeLayout(False)
TP_RULES_LIST_LEFT.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents TXT_UP_INTERVAL As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_PERSONAL_RULE As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CONTAINER_LIST As ToolStripContainer
Private WithEvents LIST_RULES As ListBox
Private WithEvents OPT_RULES_LIST As RadioButton
Private WithEvents CH_PROTECTED As CheckBox
Private WithEvents CH_FORCE_UPDATE As CheckBox
Private WithEvents CH_LOG_ERR As CheckBox
Private WithEvents CH_RULES_REPLACE_CONFIG As CheckBox
Private WithEvents CH_UPDATE_CONF As CheckBox
Private WithEvents CH_UPDATE_RULES_CONST As CheckBox
Private WithEvents CH_CONFIG_MANUAL_MODE As CheckBox
End Class
End Namespace

View File

@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="TP_RULES_LIST.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_RULES_LIST_LEFT.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="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_RULES_LIST_LEFT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -0,0 +1,165 @@
' Copyright (C) Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls.Base
Imports PersonalUtilities.Forms.Toolbars
Namespace API.OnlyFans
Friend Class OnlyFansAdvancedSettingsForm
#Region "Declarations"
Private WithEvents MyDefs As DefaultFormOptions
Friend Property CurrentRulesEnv As DynamicRulesEnv
Private ReadOnly Property CurrentRulesEnv_LIST As DynamicRulesEnv
#End Region
#Region "Initializer"
Friend Sub New(ByVal rules As DynamicRulesEnv)
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
CurrentRulesEnv = rules
CurrentRulesEnv_LIST = New DynamicRulesEnv
CurrentRulesEnv_LIST.Copy(rules, False)
End Sub
#End Region
#Region "Form handlers"
Private Sub OnlyFansAdvancedSettingsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddOkCancelToolbar()
.MyEditToolbar = New EditToolbar(Me,, CONTAINER_LIST.TopToolStripPanel) With {.Buttons = Nothing}
.MyEditToolbar.AddThisToolbar()
With CurrentRulesEnv
Select Case .Mode
Case DynamicRulesEnv.Modes.List : OPT_RULES_LIST.Checked = True
Case DynamicRulesEnv.Modes.Personal : TXT_PERSONAL_RULE.Checked = True
End Select
CH_LOG_ERR.Checked = .AddErrorsToLog
CH_RULES_REPLACE_CONFIG.Checked = .RulesReplaceConfig
CH_UPDATE_RULES_CONST.Checked = .RulesUpdateConst
CH_CONFIG_MANUAL_MODE.Checked = .RulesConfigManualMode
CH_UPDATE_CONF.Checked = .ConfigAutoUpdate
TXT_UP_INTERVAL.Text = .UpdateInterval
If Not .PersonalRule.IsEmptyString Then TXT_PERSONAL_RULE.Text = .PersonalRule
Refill()
CH_PROTECTED.Checked = .ProtectFile
CH_FORCE_UPDATE.Checked = .RulesForceUpdateRequired
End With
.MyFieldsCheckerE = New FieldsChecker
.MyFieldsCheckerE.AddControl(Of Integer)(TXT_UP_INTERVAL, TXT_UP_INTERVAL.CaptionText,,
New FieldsCheckerProviderSimple(Function(v) IIf(AConvert(Of Integer)(v, 0, EDP.ReturnValue) > 0, v, Nothing),
"The value of [{0}] field must be greater than 0"))
.MyFieldsCheckerE.EndLoaderOperations()
.EndLoaderOperations()
End With
End Sub
Private Sub OnlyFansAdvancedSettingsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
CurrentRulesEnv_LIST.Dispose()
End Sub
#End Region
#Region "Refill"
Private Sub Refill()
With CurrentRulesEnv_LIST
Dim ls% = _LatestSelected
LIST_RULES.Items.Clear()
If .Count > 0 Then LIST_RULES.Items.AddRange(.Select(Function(r) r.UrlRepo).Cast(Of Object).ToArray)
Dim lim% = LIST_RULES.Items.Count - 1
If (ls - 1).ValueBetween(0, lim) Then
ls -= 1
ElseIf (ls + 1).ValueBetween(0, lim) Then
ls += 1
End If
If ls.ValueBetween(0, lim) Then LIST_RULES.SelectedIndex = ls Else ls = -1
_LatestSelected = ls
End With
End Sub
#End Region
#Region "OK, Cancel"
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
If MyDefs.MyFieldsChecker.AllParamsOK Then
With CurrentRulesEnv
.Copy(CurrentRulesEnv_LIST, True)
.ProtectFile = CH_PROTECTED.Checked
.UpdateInterval = AConvert(Of Integer)(TXT_UP_INTERVAL.Text, DynamicRulesEnv.UpdateIntervalDefault)
.Mode = If(TXT_PERSONAL_RULE.Checked, DynamicRulesEnv.Modes.Personal, DynamicRulesEnv.Modes.List)
.PersonalRule = TXT_PERSONAL_RULE.Text
.RulesReplaceConfig = CH_RULES_REPLACE_CONFIG.Checked
.RulesUpdateConst = CH_UPDATE_RULES_CONST.Checked
.RulesConfigManualMode = CH_CONFIG_MANUAL_MODE.Checked
.ConfigAutoUpdate = CH_UPDATE_CONF.Checked
.AddErrorsToLog = CH_LOG_ERR.Checked
If CH_FORCE_UPDATE.Checked Then .RulesForceUpdateRequired = True
.NeedToSave = True
End With
MyDefs.CloseForm()
End If
End Sub
#End Region
#Region "Add, Delete"
Private Sub MyDefs_ButtonAddClick(ByVal Sender As Object, ByVal e As EditToolbarEventArgs) Handles MyDefs.ButtonAddClick
Const msgTitle$ = "Add a rule"
Dim i%
Dim rule As DynamicRulesValue
Dim r$ = InputBoxE("Enter a valid rules URL:", msgTitle)
If Not r.IsEmptyString Then
rule = Rules.ParseURL(r)
If rule.Valid Then
i = CurrentRulesEnv_LIST.IndexOf(r)
If i >= 0 Then
MsgBoxE({$"The rule you entered already exists:{vbCr}{rule.UrlRepo}", msgTitle}, vbCritical)
Else
CurrentRulesEnv_LIST.Add(rule, False, False)
Refill()
End If
Else
MsgBoxE({$"The rule you entered has an incompatible format:{vbCr}{r}", msgTitle}, vbCritical)
End If
End If
End Sub
Private Sub MyDefs_ButtonDeleteClickE(ByVal Sender As Object, ByVal e As EditToolbarEventArgs) Handles MyDefs.ButtonDeleteClickE
If _LatestSelected.ValueBetween(0, LIST_RULES.Items.Count - 1) Then
Dim r$ = LIST_RULES.Items(_LatestSelected)
If MsgBoxE({$"Are you sure you want to delete the following rule?{vbCr}{r}", "Delete a rule"}, vbExclamation,,, {"Process", "Cancel"}) = 0 Then
If CurrentRulesEnv_LIST.RemoveAt(_LatestSelected) Then
LIST_RULES.Items.RemoveAt(_LatestSelected)
Refill()
Else
MsgBoxE({$"The following rule cannot be deleted:{vbCr}{r}", "Delete a rule"}, vbCritical)
End If
End If
End If
End Sub
#End Region
#Region "Options"
Private Sub TXT_UP_INTERVAL_ActionOnButtonClick(ByVal Sender As Object, ByVal e As ActionButtonEventArgs) Handles TXT_UP_INTERVAL.ActionOnButtonClick
If e.DefaultButton = ActionButton.DefaultButtons.Refresh Then TXT_UP_INTERVAL.Text = DynamicRulesEnv.UpdateIntervalDefault
End Sub
Private Sub TXT_PERSONAL_RULE_ActionOnCheckedChange(ByVal Sender As Object, ByVal e As EventArgs, ByVal Checked As Boolean) Handles TXT_PERSONAL_RULE.ActionOnCheckedChange
Mode_CheckedChanged()
End Sub
Private Sub OPT_RULES_LIST_CheckedChanged(sender As Object, e As EventArgs)
Mode_CheckedChanged()
End Sub
Private Sub Mode_CheckedChanged()
Dim e As Boolean = TXT_PERSONAL_RULE.Checked
TXT_PERSONAL_RULE.Enabled(False) = e
CONTAINER_LIST.Enabled = Not e
CH_PROTECTED.Enabled = Not e
CH_FORCE_UPDATE.Enabled = Not e
End Sub
#End Region
#Region "List handlers"
Private _LatestSelected As Integer = -1
Private Sub LIST_RULES_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_RULES.SelectedIndexChanged
_LatestSelected = LIST_RULES.SelectedIndex
End Sub
#End Region
End Class
End Namespace

View File

@@ -9,17 +9,17 @@
Imports SCrawler.API.Base Imports SCrawler.API.Base
Imports SCrawler.Plugin Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Tools.Web.Clients Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Cookies Imports PersonalUtilities.Tools.Web.Cookies
Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Functions.RegularExpressions
Imports DN = SCrawler.API.Base.DeclaredNames Imports DN = SCrawler.API.Base.DeclaredNames
Namespace API.OnlyFans Namespace API.OnlyFans
<Manifest("AndyProgram_OnlyFans"), SavedPosts, SpecialForm(False), SeparatedTasks(1)> <Manifest("AndyProgram_OnlyFans"), SavedPosts, SpecialForm(False), SpecialForm(True), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations" #Region "Declarations"
#Region "Categories" #Region "Categories"
Private Const CAT_OFS As String = "OF-Scraper support" Private Const CAT_OFS As String = "OF-Scraper support"
Private Const CAT_ERRORS As String = "Errors"
#End Region #End Region
#Region "Options" #Region "Options"
<PropertyOption(ControlText:="Download timeline", ControlToolTip:="Download user timeline", Category:=DN.CAT_UserDefs), PXML, PClonable> <PropertyOption(ControlText:="Download timeline", ControlToolTip:="Download user timeline", Category:=DN.CAT_UserDefs), PXML, PClonable>
@@ -74,29 +74,18 @@ Namespace API.OnlyFans
Return String.Empty Return String.Empty
End Function End Function
#End Region #End Region
#Region "Rules" #Region "Errors"
<PXML("LastDateUpdated")> Private ReadOnly Property LastDateUpdated_XML As PropertyValue <PClonable, PXML("UpdateRules401")> Private ReadOnly Property UpdateRules401_XML As PropertyValue
Friend Property LastDateUpdated As Date <PropertyOption(ControlText:="Try updating rules when you get a 401 error", Category:=CAT_ERRORS), HiddenControl>
Friend ReadOnly Property UpdateRules401 As PropertyValue
Get Get
Return LastDateUpdated_XML.Value If Not DefaultInstance Is Nothing Then
Return DirectCast(DefaultInstance, SiteSettings).UpdateRules401_XML
Else
Return UpdateRules401_XML
End If
End Get End Get
Set(ByVal d As Date)
LastDateUpdated_XML.Value = d
End Set
End Property End Property
<PropertyOption(ControlText:="Use old authorization rules",
ControlToolTip:="Use old dynamic rules (from 'DATAHOARDERS') or new ones (from 'DIGITALCRIMINALS')." & vbCr &
"Change this value only if you know what you are doing.", IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property UseOldAuthRules As PropertyValue
<PropertyOption(ControlText:="Dynamic rules update", ControlToolTip:="'Dynamic rules' update interval (minutes). Default: 1440",
LeftOffset:=110, IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property DynamicRulesUpdateInterval As PropertyValue
<Provider(NameOf(DynamicRulesUpdateInterval), FieldsChecker:=True)>
Private ReadOnly Property DynamicRulesUpdateIntervalProvider As IFormatProvider
<PropertyOption(ControlText:="Dynamic rules",
ControlToolTip:="Overwrite 'Dynamic rules' with this URL" & vbCr &
"Change this value only if you know what you are doing.", IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property DynamicRules As PropertyValue
#End Region #End Region
#Region "OFScraper" #Region "OFScraper"
<PClonable, PXML("OFScraperPath")> Private ReadOnly Property OFScraperPath_XML As PropertyValue <PClonable, PXML("OFScraperPath")> Private ReadOnly Property OFScraperPath_XML As PropertyValue
@@ -150,7 +139,10 @@ Namespace API.OnlyFans
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("OnlyFans", ".onlyfans.com", AccName, Temp, My.Resources.SiteResources.OnlyFansIcon_32, My.Resources.SiteResources.OnlyFansPic_32) MyBase.New("OnlyFans", ".onlyfans.com", AccName, Temp, My.Resources.SiteResources.OnlyFansIcon_32, My.Resources.SiteResources.OnlyFansPic_32)
CheckOFSConfig() If Rules Is Nothing Then
Rules = New DynamicRulesEnv
Rules.Update(False, True)
End If
_AllowUserAgentUpdate = False _AllowUserAgentUpdate = False
@@ -184,13 +176,6 @@ Namespace API.OnlyFans
DownloadHighlights = New PropertyValue(True) DownloadHighlights = New PropertyValue(True)
DownloadChatMedia = New PropertyValue(True) DownloadChatMedia = New PropertyValue(True)
LastDateUpdated_XML = New PropertyValue(Now.AddYears(-1), GetType(Date))
'URGENT: OF [UseOldAuthRules = True]
UseOldAuthRules = New PropertyValue(True)
DynamicRulesUpdateInterval = New PropertyValue(60 * 24)
DynamicRulesUpdateIntervalProvider = New FieldsCheckerProviderSimple(Function(v) IIf(AConvert(Of Integer)(v, 0) > 0, v, Nothing),
"The value of [{0}] field must be greater than 0")
DynamicRules = New PropertyValue(String.Empty, GetType(String))
OFScraperPath_XML = New PropertyValue(String.Empty, GetType(String)) OFScraperPath_XML = New PropertyValue(String.Empty, GetType(String))
If ACheck(OFScraperPath_XML.Value) Then If ACheck(OFScraperPath_XML.Value) Then
Dim f As SFile = OFScraperPath_XML.Value Dim f As SFile = OFScraperPath_XML.Value
@@ -207,6 +192,8 @@ Namespace API.OnlyFans
KeyModeDefault_XML = New PropertyValue(KeyModeDefault_Default) KeyModeDefault_XML = New PropertyValue(KeyModeDefault_Default)
Keydb_Api_XML = New PropertyValue(String.Empty, GetType(String)) Keydb_Api_XML = New PropertyValue(String.Empty, GetType(String))
UpdateRules401_XML = New PropertyValue(False)
UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "onlyfans.com/"), 1, EDP.ReturnValue) UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "onlyfans.com/"), 1, EDP.ReturnValue)
UrlPatternUser = "https://onlyfans.com/{0}" UrlPatternUser = "https://onlyfans.com/{0}"
ImageVideoContains = "onlyfans.com" ImageVideoContains = "onlyfans.com"
@@ -218,21 +205,28 @@ Namespace API.OnlyFans
End Function End Function
#End Region #End Region
#Region "Update" #Region "Update"
Private __UseOldAuthRules As Boolean = True
Private __DynamicRules As String = String.Empty
Friend Overrides Sub BeginUpdate() Friend Overrides Sub BeginUpdate()
__UseOldAuthRules = UseOldAuthRules.Value _TempSettingsEnv.DisposeIfReady
__DynamicRules = AConvert(Of String)(DynamicRules.Value, String.Empty) _TempSettingsEnv = Nothing
MyBase.BeginUpdate() MyBase.BeginUpdate()
End Sub End Sub
Friend Overrides Sub Update() Friend Overrides Sub Update()
If _SiteEditorFormOpened Then If _SiteEditorFormOpened Then
If Not __UseOldAuthRules = CBool(UseOldAuthRules.Value) Or Not AEquals(Of String)(__DynamicRules, DynamicRules.Value) Then _
LastDateUpdated = Now.AddYears(-1)
Responser.Cookies.Changed = False Responser.Cookies.Changed = False
If If(_TempSettingsEnv?.NeedToSave, False) Then Rules.Copy(_TempSettingsEnv, True) : Rules.Save()
End If End If
MyBase.Update() MyBase.Update()
End Sub End Sub
Friend Overrides Sub EndUpdate()
_TempSettingsEnv.DisposeIfReady
_TempSettingsEnv = Nothing
MyBase.EndUpdate()
End Sub
Private _TempSettingsEnv As DynamicRulesEnv = Nothing
Friend Overrides Sub OpenSettingsForm()
If _TempSettingsEnv Is Nothing Then _TempSettingsEnv = New DynamicRulesEnv : _TempSettingsEnv.Copy(Rules, False)
Using f As New OnlyFansAdvancedSettingsForm(_TempSettingsEnv) : f.ShowDialog() : End Using
End Sub
#End Region #End Region
#Region "Download" #Region "Download"
Friend Overrides Function BaseAuthExists() As Boolean Friend Overrides Function BaseAuthExists() As Boolean

View File

@@ -91,6 +91,7 @@ Namespace API.OnlyFans
End Sub End Sub
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken) Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
Try Try
_DownloadingException_AuthFileUpdate = False
If Not MySettings.SessionAborted Then If Not MySettings.SessionAborted Then
ValidateOFScraper() ValidateOFScraper()
_AbsMediaIndex = 0 _AbsMediaIndex = 0
@@ -393,6 +394,14 @@ Namespace API.OnlyFans
Loop While Not _complete Loop While Not _complete
End Sub End Sub
#End Region #End Region
Private Function GetMediaURL(ByVal m As EContainer) As String
Dim v$
For Each node As Object() In FilesSources
v = If(m.ItemF(node)?.Value, String.Empty)
If Not v.IsEmptyString Then Return v
Next
Return String.Empty
End Function
Private Function TryCreateMedia(ByVal n As EContainer, ByVal PostID As String, Optional ByVal PostDate As String = Nothing, Private Function TryCreateMedia(ByVal n As EContainer, ByVal PostID As String, Optional ByVal PostDate As String = Nothing,
Optional ByRef Result As Boolean = False, Optional ByVal IsHL As Boolean = False, Optional ByRef Result As Boolean = False, Optional ByVal IsHL As Boolean = False,
Optional ByVal SpecFolder As String = Nothing, Optional ByVal PostUserID As String = Nothing, Optional ByVal SpecFolder As String = Nothing, Optional ByVal PostUserID As String = Nothing,
@@ -404,11 +413,14 @@ Namespace API.OnlyFans
With n("media") With n("media")
If .ListExists Then If .ListExists Then
For Each m In .Self For Each m In .Self
If IsHL Then postUrl = GetMediaURL(m)
postUrl = m.Value({"files", "source"}, "url") 'If IsHL Then
Else ' 'postUrl = m.Value({"files", "source"}, "url")
postUrl = m.Value({"source"}, "source").IfNullOrEmpty(m.Value("full")) ' postUrl = GetMediaURL(m)
End If 'Else
' 'postUrl = m.Value({"source"}, "source").IfNullOrEmpty(m.Value("full"))
' postUrl = GetMediaURL(m)
'End If
postUrlBase = String.Empty postUrlBase = String.Empty
Select Case m.Value("type") Select Case m.Value("type")
Case "photo" : t = UTypes.Picture : ext = "jpg" Case "photo" : t = UTypes.Picture : ext = "jpg"
@@ -537,45 +549,16 @@ Namespace API.OnlyFans
End Sub End Sub
#End Region #End Region
#Region "Auth" #Region "Auth"
Private ReadOnly Property AuthFile As SFile Private Function UpdateSignature(ByVal Path As String) As Boolean
Get
Dim f As SFile = MySettings.Responser.File
f.Name &= "_Auth"
f.Extension = "json"
Return f
End Get
End Property
Private Function UpdateSignature(ByVal Path As String, Optional ByVal ForceUpdateAuth As Boolean = False,
Optional ByVal Round As Integer = 0) As Boolean
Try Try
If UpdateAuthFile(ForceUpdateAuth) Then If Not Rules.Update(False) Then Rules.Update(True)
If Rules.Exists Then
Const nullMsg$ = "The auth parameter(s) is null" Const nullMsg$ = "The auth parameter(s) is null"
Const formatMidPart$ = ":{0}:{1:x}:" Dim j As EContainer = Rules.CurrentContainer
Dim j As EContainer
Try
j = JsonDocument.Parse(AuthFile.GetText)
Catch jex As Exception
If Round = 0 Then
AuthFile.Delete()
UpdateAuthFile(True)
Return UpdateSignature(Path, ForceUpdateAuth, Round + 1)
Else
MySettings.SessionAborted = True
Return False
End If
End Try
If Not j Is Nothing Then If Not j Is Nothing Then
Dim pattern$ = j.Value("format") Dim pattern$ = DynamicRulesEnv.GetFormat(j)
If Not pattern.IsEmptyString Then If pattern.IsEmptyString Then Throw New ArgumentNullException("format", nullMsg)
pattern = pattern.Replace("{}", "{0}").Replace("{:x}", "{1:x}")
ElseIf Not j.Value("prefix").IsEmptyString And Not j.Value("suffix").IsEmptyString Then
pattern = j.Value("prefix") & formatMidPart & j.Value("suffix")
ElseIf Not j.Value("start").IsEmptyString And Not j.Value("end").IsEmptyString Then
pattern = j.Value("start") & formatMidPart & j.Value("end")
Else
Throw New ArgumentNullException("format", nullMsg)
End If
Dim li%() = j("checksum_indexes").Select(Function(e) CInt(e(0).Value)).ToArray Dim li%() = j("checksum_indexes").Select(Function(e) CInt(e(0).Value)).ToArray
@@ -599,42 +582,16 @@ Namespace API.OnlyFans
Responser.Headers.Add(HeaderSign, sign) Responser.Headers.Add(HeaderSign, sign)
Responser.Headers.Add(HeaderTime, t) Responser.Headers.Add(HeaderTime, t)
j.Dispose()
Return True Return True
End If End If
Else
MySettings.SessionAborted = True
End If End If
Return False Return False
Catch ex As Exception Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"{ToStringForLog()}: UpdateSignature", False) Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"{ToStringForLog()}: UpdateSignature", False)
End Try End Try
End Function End Function
Private Function UpdateAuthFile(ByVal Force As Boolean) As Boolean
Const urlOld$ = "https://raw.githubusercontent.com/DATAHOARDERS/dynamic-rules/main/onlyfans.json"
Const urlNew$ = "https://raw.githubusercontent.com/DIGITALCRIMINALS/dynamic-rules/main/onlyfans.json"
Try
If MySettings.LastDateUpdated.AddMinutes(CInt(MySettings.DynamicRulesUpdateInterval.Value)) < Now Or Not AuthFile.Exists Or Force Then
Dim r$ = GetWebString(If(ACheck(Of String)(MySettings.DynamicRules.Value),
CStr(MySettings.DynamicRules.Value),
IIf(MySettings.UseOldAuthRules.Value, urlOld, urlNew)),, EDP.ReturnValue)
Dim checkFormat As Func(Of EContainer, Boolean) =
Function(jj) Not jj.Value("format").IsEmptyString OrElse
(Not jj.Value("prefix").IsEmptyString And Not jj.Value("suffix").IsEmptyString) OrElse
(Not jj.Value("start").IsEmptyString And Not jj.Value("end").IsEmptyString)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
If j.ListExists Then
If checkFormat(j) And j("checksum_indexes").ListExists And
Not j.Value("static_param").IsEmptyString And Not j.Value("checksum_constant").IsEmptyString Then _
TextSaver.SaveTextToFile(r, AuthFile, True, False, EDP.ThrowException) : MySettings.LastDateUpdated = Now
End If
End Using
End If
End If
Return AuthFile.Exists
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"{ToStringForLog()}: UpdateAuthFile", False)
End Try
End Function
Private Function GetHashSha1(ByVal Input As String) As String Private Function GetHashSha1(ByVal Input As String) As String
Dim s As New Security.Cryptography.SHA1CryptoServiceProvider Dim s As New Security.Cryptography.SHA1CryptoServiceProvider
Dim inputBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(Input) Dim inputBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(Input)
@@ -666,35 +623,51 @@ Namespace API.OnlyFans
Private Function OFS_CreateConfig() As SFile Private Function OFS_CreateConfig() As SFile
Try Try
Const confMainPattern$ = "{0}"": ""([^""]*)""" Const confMainPattern$ = "{0}"": ""([^""]*)"""
Const confMainPatternRulesManual$ = "DYNAMIC_RULE"": (""[^""]*"")"
If OFSCache Is Nothing Then OFSCache = If(IsSingleObjectDownload, Settings.Cache.NewInstance, CreateCache()) If OFSCache Is Nothing Then OFSCache = If(IsSingleObjectDownload, Settings.Cache.NewInstance, CreateCache())
Dim currentCache As CacheKeeper = OFSCache.NewInstance Dim currentCache As CacheKeeper = OFSCache.NewInstance
currentCache.Validate() currentCache.Validate()
Dim cacheRoot As SFile = currentCache.NewPath Dim cacheRoot As SFile = currentCache.NewPath
cacheRoot.Exists(SFO.Path, True, EDP.ThrowException) cacheRoot.Exists(SFO.Path, True, EDP.ThrowException)
Dim f As SFile = OFScraperConfigPatternFile Dim f As SFile = Rules.OFScraperConfigPatternFile
Dim configText$ Dim configText$
CheckOFSConfig()
If f.Exists Then If f.Exists Then
Dim replaceValue$ = String.Empty Dim replaceValue$ = String.Empty
Dim rp As RParams = RParams.DMS(String.Empty, 1, RegexReturn.Replace, RegexOptions.IgnoreCase, Dim rp As RParams = RParams.DMS(String.Empty, 1, RegexReturn.Replace, RegexOptions.IgnoreCase,
CType(Function(input) replaceValue, Func(Of String, String)), String.Empty, EDP.ReturnValue) CType(Function(input) replaceValue, Func(Of String, String)), String.Empty, EDP.ReturnValue)
Dim ff As SFile Dim ff As SFile
configText = f.GetText configText = f.GetText
Dim updateConf As Action(Of String, String) = Sub(ByVal patternValue As String, ByVal __replaceValue As String) Dim updateConf As Action(Of String, String, Boolean) =
rp.Pattern = String.Format(confMainPattern, patternValue) Sub(ByVal patternValue As String, ByVal __replaceValue As String, ByVal __isRules As Boolean)
rp.Nothing = configText rp.Pattern = String.Format(IIf(__isRules, confMainPatternRulesManual, confMainPattern), patternValue)
replaceValue = __replaceValue rp.Nothing = configText
configText = RegexReplace(configText, rp) replaceValue = __replaceValue
End Sub configText = RegexReplace(configText, rp)
End Sub
If Not configText.IsEmptyString Then If Not configText.IsEmptyString Then
updateConf("save_location", cacheRoot.PathNoSeparator.Replace("\", "/")) updateConf("save_location", cacheRoot.PathNoSeparator.Replace("\", "/"), False)
If ACheck(MySettings.OFScraperMP4decrypt.Value) Then If ACheck(MySettings.OFScraperMP4decrypt.Value) Then
ff = CStr(MySettings.OFScraperMP4decrypt.Value) ff = CStr(MySettings.OFScraperMP4decrypt.Value)
If ff.Exists Then updateConf("mp4decrypt", ff.ToString.Replace("\", "/")) If ff.Exists Then updateConf("mp4decrypt", ff.ToString.Replace("\", "/"), False)
End If
If Settings.FfmpegFile.Exists Then updateConf("ffmpeg", Settings.FfmpegFile.File.ToString.Replace("\", "/"), False)
updateConf("key-mode-default", CStr(MySettings.KeyModeDefault.Value).IfNullOrEmpty(SiteSettings.KeyModeDefault_Default), False)
updateConf("keydb_api", CStr(MySettings.Keydb_Api.Value), False)
If Rules.RulesReplaceConfig Then
If Rules.RulesConfigManualMode Then
updateConf(DynamicRulesEnv.DynamicRulesConfig_Mode_NodeName, "manual", False)
configText = configText.Replace(DynamicRulesEnv.DynamicRulesConfigNodeName_URL, DynamicRulesEnv.DynamicRulesConfigNodeName_RULES)
updateConf(DynamicRulesEnv.DynamicRulesConfigNodeName_RULES, Rules.CurrentContainerRulesText, True)
Else
Dim confUrlNode$ = If(Rules.RulesConstants.ContainsKey(DynamicRulesEnv.DynamicRulesConfigNodeName_URL_CONST_NAME),
Rules.RulesConstants(DynamicRulesEnv.DynamicRulesConfigNodeName_URL_CONST_NAME),
DynamicRulesEnv.DynamicRulesConfigNodeName_URL)
updateConf(DynamicRulesEnv.DynamicRulesConfigNodeName_URL, Rules.CurrentRule.UrlRaw, False)
configText = configText.Replace(DynamicRulesEnv.DynamicRulesConfigNodeName_URL, confUrlNode)
If Rules.RulesConstants.ContainsKey(DynamicRulesEnv.DynamicRulesConfig_Mode_NodeName) Then _
updateConf(DynamicRulesEnv.DynamicRulesConfig_Mode_NodeName, Rules.RulesConstants(DynamicRulesEnv.DynamicRulesConfig_Mode_NodeName), False)
End If
End If End If
If Settings.FfmpegFile.Exists Then updateConf("ffmpeg", Settings.FfmpegFile.File.ToString.Replace("\", "/"))
updateConf("key-mode-default", CStr(MySettings.KeyModeDefault.Value).IfNullOrEmpty(SiteSettings.KeyModeDefault_Default))
updateConf("keydb_api", CStr(MySettings.Keydb_Api.Value))
f = currentCache f = currentCache
f.Name = "config" f.Name = "config"
f.Extension = "json" f.Extension = "json"
@@ -787,14 +760,20 @@ Namespace API.OnlyFans
Private _DownloadingException_AuthFileUpdate As Boolean = False Private _DownloadingException_AuthFileUpdate As Boolean = False
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False, Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
Optional ByVal EObj As Object = Nothing) As Integer Optional ByVal EObj As Object = Nothing) As Integer
If Responser.StatusCode = Net.HttpStatusCode.BadRequest Then '400 If Responser.StatusCode = Net.HttpStatusCode.BadRequest Or
If Not _DownloadingException_AuthFileUpdate AndAlso UpdateAuthFile(True) Then (Responser.StatusCode = Net.HttpStatusCode.Unauthorized And CBool(MySettings.UpdateRules401.Value)) Then '400, [401]
If Not _DownloadingException_AuthFileUpdate AndAlso Rules.Update(True) Then
_DownloadingException_AuthFileUpdate = True _DownloadingException_AuthFileUpdate = True
Return 2 Return 2
Else Else
MySettings.SessionAborted = True MySettings.SessionAborted = True
MyMainLOG = $"{ToStringForLog()} [{CInt(Responser.StatusCode)}]: OnlyFans credentials expired" MyMainLOG = $"{ToStringForLog()} [{CInt(Responser.StatusCode)}]: OnlyFans credentials expired"
Return 1 If Responser.StatusCode = Net.HttpStatusCode.BadRequest Then
Return 1
Else
MyMainLOG = $"{ToStringForLog()}: Rules updated (401)"
Return 3
End If
End If End If
ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then '404 ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then '404
UserExists = False UserExists = False

View File

@@ -21,6 +21,6 @@ Namespace API.Reddit
Friend ReadOnly UrlBasePattern As RParams = RParams.DM("(?<=/)([^/]+?\.[\w]{3,4})(?=(\?|\Z))", 0) Friend ReadOnly UrlBasePattern As RParams = RParams.DM("(?<=/)([^/]+?\.[\w]{3,4})(?=(\?|\Z))", 0)
Friend ReadOnly VideoRegEx As RParams = RParams.DM("http.{0,1}://[^" & Chr(34) & "]+?mp4", 0) Friend ReadOnly VideoRegEx As RParams = RParams.DM("http.{0,1}://[^" & Chr(34) & "]+?mp4", 0)
Private ReadOnly EUR_PROVIDER As New ANumbers(ANumbers.Cultures.EUR) Private ReadOnly EUR_PROVIDER As New ANumbers(ANumbers.Cultures.EUR)
Friend ReadOnly UnixDate32ProviderReddit As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnix32(AConvert(Of Integer)(v, EUR_PROVIDER, v), n, e)) Friend ReadOnly UnixDate32ProviderReddit As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnix32(AConvert(Of Double)(v, EUR_PROVIDER, v), n, e))
End Module End Module
End Namespace End Namespace

View File

@@ -85,7 +85,7 @@ Namespace API.Reddit
ApiClientSecret = New PropertyValue(String.Empty, GetType(String)) ApiClientSecret = New PropertyValue(String.Empty, GetType(String))
BearerToken = New PropertyValue(token, GetType(String), Sub(v) Responser.Headers.Add(DeclaredNames.Header_Authorization, v)) BearerToken = New PropertyValue(token, GetType(String), Sub(v) Responser.Headers.Add(DeclaredNames.Header_Authorization, v))
BearerTokenUseCurl = New PropertyValue(True) BearerTokenUseCurl = New PropertyValue(True)
TokenUpdateInterval = New PropertyValue(60 * 12) TokenUpdateInterval = New PropertyValue(360)
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
BearerTokenDateUpdate = New PropertyValue(Now.AddYears(-1)) BearerTokenDateUpdate = New PropertyValue(Now.AddYears(-1))
UseTokenForTimelines = New PropertyValue(False) UseTokenForTimelines = New PropertyValue(False)
@@ -101,6 +101,14 @@ Namespace API.Reddit
ImageVideoContains = "reddit.com" ImageVideoContains = "reddit.com"
UserRegex = RParams.DM("[htps:/]{7,8}.*?reddit.com/([user]{1,4})/([^/\?&]+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue) UserRegex = RParams.DM("[htps:/]{7,8}.*?reddit.com/([user]{1,4})/([^/\?&]+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
End Sub End Sub
Private Const SettingsVersionCurrent As Integer = 1
Friend Overrides Sub EndInit()
If CInt(SettingsVersion.Value) < SettingsVersionCurrent Then
SettingsVersion.Value = SettingsVersionCurrent
TokenUpdateInterval.Value = 360
End If
MyBase.EndInit()
End Sub
#End Region #End Region
#Region "GetInstance" #Region "GetInstance"
Friend Overrides Function GetInstance(ByVal What As Download) As IPluginContentProvider Friend Overrides Function GetInstance(ByVal What As Download) As IPluginContentProvider

View File

@@ -15,7 +15,7 @@ Imports PersonalUtilities.Functions.RegularExpressions
Imports IG = SCrawler.API.Instagram.SiteSettings Imports IG = SCrawler.API.Instagram.SiteSettings
Imports DN = SCrawler.API.Base.DeclaredNames Imports DN = SCrawler.API.Base.DeclaredNames
Namespace API.ThreadsNet Namespace API.ThreadsNet
<Manifest("AndyProgram_ThreadsNet"), SeparatedTasks(1)> <Manifest("AndyProgram_ThreadsNet"), SavedPosts, SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations" #Region "Declarations"
#Region "Authorization" #Region "Authorization"

View File

@@ -101,7 +101,12 @@ Namespace API.ThreadsNet
Else Else
DefaultParser_SkipPost = AddressOf SkipPost DefaultParser_SkipPost = AddressOf SkipPost
End If End If
DownloadData(String.Empty, Token) If IsSavedPosts Then
DefaultParser_ElemNode = {"node", "thread_items", 0, "post"}
DownloadSavedPosts(String.Empty, Token)
Else
DownloadData(String.Empty, Token)
End If
If _TempMediaList.Count > 0 Then FirstLoadingDone = True : setMaxPostDate.Invoke(_TempMediaList) If _TempMediaList.Count > 0 Then FirstLoadingDone = True : setMaxPostDate.Invoke(_TempMediaList)
Catch ex As Exception Catch ex As Exception
errorFound = True errorFound = True
@@ -116,11 +121,15 @@ Namespace API.ThreadsNet
End Sub End Sub
Private Function IsPinnedPost(ByVal Items As IEnumerable(Of EContainer), ByVal Index As Integer) As Boolean Private Function IsPinnedPost(ByVal Items As IEnumerable(Of EContainer), ByVal Index As Integer) As Boolean
Try Try
If MaxLastDownDate.HasValue Then If IsSavedPosts Then
Dim d As Date? = AConvert(Of Date)(Items(Index).ItemF(DefaultParser_ElemNode_Default).Value("taken_at"), UnixDate32Provider, Nothing) Return False
If d.HasValue Then Return d.Value < MaxLastDownDate.Value Else
If MaxLastDownDate.HasValue Then
Dim d As Date? = AConvert(Of Date)(Items(Index).ItemF(DefaultParser_ElemNode_Default).Value("taken_at"), UnixDate32Provider, Nothing)
If d.HasValue Then Return d.Value < MaxLastDownDate.Value
End If
Return Not FirstLoadingDone
End If End If
Return Not FirstLoadingDone
Catch ex As Exception Catch ex As Exception
LogError(ex, "IsPinnedPost") LogError(ex, "IsPinnedPost")
Return Not FirstLoadingDone Return Not FirstLoadingDone
@@ -141,22 +150,32 @@ Namespace API.ThreadsNet
Responser.Headers.Add(IGS.Header_CSRF_TOKEN, csrf) Responser.Headers.Add(IGS.Header_CSRF_TOKEN, csrf)
End If End If
End Sub End Sub
Private Const GQL_Q As String = "https://www.threads.net/api/graphql?lsd={0}&fb_dtsg={1}&doc_id={2}&fb_api_req_friendly_name={3}&server_timestamps=true&variables={4}"
Private Const GQL_P_DOC_ID As String = "6371597506283707"
Private Const GQL_P_NAME As String = "BarcelonaProfileThreadsTabRefetchableQuery"
Private Const GQL_S_DOC_ID_1 As String = "7758166704280174"
Private Const GQL_S_NAME_1 As String = "BarcelonaSavedPageViewerQuery"
Private Const GQL_S_DOC_ID_2 As String = "8617275414954442"
Private Const GQL_S_NAME_2 As String = "BarcelonaSavedPageRefetchableQuery"
Private Sub DownloadCheckCredentials()
If Not Valid Then
Dim idIsNull As Boolean = ID.IsEmptyString
UpdateCredentials()
If idIsNull And Not ID.IsEmptyString Then _ForceSaveUserInfo = True
End If
If Not Valid Then DisableDownload() : Throw New Plugin.ExitException("Some credentials are missing")
End Sub
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken) Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken)
Const urlPattern$ = "https://www.threads.net/api/graphql?lsd={0}&variables={1}&doc_id=6371597506283707&fb_api_req_friendly_name=BarcelonaProfileThreadsTabRefetchableQuery&server_timestamps=true&fb_dtsg={2}"
Const var_init$ = """userID"":""{0}""" Const var_init$ = """userID"":""{0}"""
Const var_cursor$ = """after"":""{1}"",""before"":null,""first"":25,""last"":null,""userID"":""{0}"",""__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaIsFeedbackHubEnabledrelayprovider"":false" Const var_cursor$ = """after"":""{1}"",""before"":null,""first"":25,""last"":null,""userID"":""{0}"",""__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaIsFeedbackHubEnabledrelayprovider"":false"
Dim URL$ = String.Empty Dim URL$ = String.Empty
Try Try
If Not Valid Then DownloadCheckCredentials()
Dim idIsNull As Boolean = ID.IsEmptyString
UpdateCredentials()
If idIsNull And Not ID.IsEmptyString Then _ForceSaveUserInfo = True
End If
If Not Valid Then DisableDownload() : Throw New Plugin.ExitException("Some credentials are missing")
Responser.Method = "POST" Responser.Method = "POST"
Responser.Referer = $"https://www.threads.net/@{NameTrue}" Responser.Referer = $"https://www.threads.net/@{NameTrue}"
Responser.Headers.Add(GQL_HEADER_FB_LSD, Token_lsd) Responser.Headers.Add(GQL_HEADER_FB_LSD, Token_lsd)
Responser.Headers.Add(GQL_HEADER_FB_FRINDLY_NAME, GQL_P_NAME)
Dim nextCursor$ = String.Empty Dim nextCursor$ = String.Empty
Dim dataFound As Boolean = False Dim dataFound As Boolean = False
@@ -169,7 +188,7 @@ Namespace API.ThreadsNet
End If End If
vars = SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & vars & "}") vars = SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & vars & "}")
URL = String.Format(urlPattern, Token_lsd, vars, Token_dtsg_Var) URL = String.Format(GQL_Q, Token_lsd, Token_dtsg_Var, GQL_P_DOC_ID, GQL_P_NAME, vars)
Using j As EContainer = GetDocument(URL, Token) Using j As EContainer = GetDocument(URL, Token)
If j.ListExists Then If j.ListExists Then
@@ -189,6 +208,47 @@ Namespace API.ThreadsNet
ProcessException(ex, Token, $"data downloading error [{URL}]") ProcessException(ex, Token, $"data downloading error [{URL}]")
End Try End Try
End Sub End Sub
Private Sub DownloadSavedPosts(ByVal Cursor As String, ByVal Token As CancellationToken)
Const var_init$ = """__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaIsInlineReelsEnabledrelayprovider"":false,""__relay_internal__pv__BarcelonaUseCometVideoPlaybackEnginerelayprovider"":false,""__relay_internal__pv__BarcelonaOptionalCookiesEnabledrelayprovider"":true,""__relay_internal__pv__BarcelonaIsTextFragmentsEnabledForPostCaptionsrelayprovider"":true,""__relay_internal__pv__BarcelonaShouldShowFediverseM075Featuresrelayprovider"":true"
Const var_cursor$ = """after"":""{0}"",""first"":25,""__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaIsInlineReelsEnabledrelayprovider"":false,""__relay_internal__pv__BarcelonaUseCometVideoPlaybackEnginerelayprovider"":false,""__relay_internal__pv__BarcelonaOptionalCookiesEnabledrelayprovider"":true,""__relay_internal__pv__BarcelonaIsTextFragmentsEnabledForPostCaptionsrelayprovider"":true,""__relay_internal__pv__BarcelonaShouldShowFediverseM075Featuresrelayprovider"":true"
Dim URL$ = String.Empty
Try
DownloadCheckCredentials()
Responser.Method = "POST"
Responser.Referer = "https://www.threads.net/"
Responser.Headers.Add(GQL_HEADER_FB_LSD, Token_lsd)
Responser.Headers.Add(GQL_HEADER_FB_FRINDLY_NAME, If(Cursor.IsEmptyString, GQL_S_NAME_1, GQL_S_NAME_2))
Dim nextCursor$ = String.Empty
Dim dataFound As Boolean = False
Dim vars$ = SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & If(Cursor.IsEmptyString, var_init, String.Format(var_cursor, Cursor)) & "}")
If Cursor.IsEmptyString Then
URL = String.Format(GQL_Q, Token_lsd, Token_dtsg_Var, GQL_S_DOC_ID_1, GQL_S_NAME_1, vars)
Else
URL = String.Format(GQL_Q, Token_lsd, Token_dtsg_Var, GQL_S_DOC_ID_2, GQL_S_NAME_2, vars)
End If
Using j As EContainer = GetDocument(URL, Token)
If j.ListExists Then
With j({"data", "xdt_viewer", "text_app_saved_media"})
If .ListExists Then
nextCursor = .Value({"page_info"}, "end_cursor")
With .Item({"edges"})
If .ListExists Then dataFound = DefaultParser(.Self, Sections.Timeline, Token)
End With
End If
End With
End If
End Using
If dataFound And Not nextCursor.IsEmptyString Then DownloadSavedPosts(nextCursor, Token)
Catch ex As Exception
ProcessException(ex, Token, $"saved posts downloading error [{URL}]")
End Try
End Sub
Private Function GetDocument(ByVal URL As String, ByVal Token As CancellationToken, Optional ByVal Round As Integer = 0) As EContainer Private Function GetDocument(ByVal URL As String, ByVal Token As CancellationToken, Optional ByVal Round As Integer = 0) As EContainer
Try Try
ThrowAny(Token) ThrowAny(Token)
@@ -206,7 +266,7 @@ Namespace API.ThreadsNet
End Try End Try
End Function End Function
Private Function UpdateCredentials(Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Private Function UpdateCredentials(Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
Dim URL$ = $"https://www.threads.net/@{NameTrue}" Dim URL$ = If(IsSavedPosts, "https://www.threads.net/", $"https://www.threads.net/@{NameTrue}")
ResetBaseTokens() ResetBaseTokens()
Dim headers As New HttpHeaderCollection Dim headers As New HttpHeaderCollection
headers.AddRange(Responser.Headers) headers.AddRange(Responser.Headers)

View File

@@ -8,6 +8,7 @@
' but WITHOUT ANY WARRANTY ' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes Imports SCrawler.Plugin.Attributes
Imports DModels = SCrawler.API.Twitter.UserData.DownloadModels Imports DModels = SCrawler.API.Twitter.UserData.DownloadModels
Imports DN = SCrawler.API.Base.DeclaredNames
Namespace API.Twitter Namespace API.Twitter
Friend Class EditorExchangeOptions Friend Class EditorExchangeOptions
Private Const DefaultOffset As Integer = 100 Private Const DefaultOffset As Integer = 100
@@ -46,6 +47,8 @@ Namespace API.Twitter
Caption:="Force apply", Caption:="Force apply",
ToolTip:="Force overrides the default parameters for the first download." & vbCr & "Applies to first download only.", LeftOffset:=DefaultOffset)> ToolTip:="Force overrides the default parameters for the first download." & vbCr & "Applies to first download only.", LeftOffset:=DefaultOffset)>
Friend Overridable Property DownloadModelForceApply As Boolean = False Friend Overridable Property DownloadModelForceApply As Boolean = False
<PSetting(Address:=SettingAddress.User, Caption:=DN.UserNameChangeCaption, ToolTip:=DN.UserNameChangeToolTip, LeftOffset:=DefaultOffset)>
Friend Overridable Property UserName As String = String.Empty
Private ReadOnly Property MySettings As Object Private ReadOnly Property MySettings As Object
Friend Sub New(ByVal s As SiteSettings) Friend Sub New(ByVal s As SiteSettings)
GifsDownload = s.GifsDownload.Value GifsDownload = s.GifsDownload.Value
@@ -80,6 +83,7 @@ Namespace API.Twitter
DownloadModelLikes = dm.Contains(DModels.Likes) DownloadModelLikes = dm.Contains(DModels.Likes)
End If End If
End If End If
UserName = u.NameTrue(True)
MySettings = u.HOST.Source MySettings = u.HOST.Source
End Sub End Sub
End Class End Class

View File

@@ -31,9 +31,9 @@ Namespace API.Twitter
#Region "Declarations" #Region "Declarations"
Private Const Label_Community As String = "Community" Private Const Label_Community As String = "Community"
Private _NameTrue As String = String.Empty Private _NameTrue As String = String.Empty
Friend Property NameTrue As String Friend Property NameTrue(Optional ByVal Exact As Boolean = False) As String
Get Get
Return _NameTrue.IfNullOrEmpty(Name) Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name))
End Get End Get
Set(ByVal NewName As String) Set(ByVal NewName As String)
_NameTrue = NewName _NameTrue = NewName
@@ -90,6 +90,7 @@ Namespace API.Twitter
GifsPrefix = .GifsPrefix GifsPrefix = .GifsPrefix
UseMD5Comparison = .UseMD5Comparison UseMD5Comparison = .UseMD5Comparison
RemoveExistingDuplicates = .RemoveExistingDuplicates RemoveExistingDuplicates = .RemoveExistingDuplicates
If RemoveExistingDuplicates Then StartMD5Checked = False
DownloadModel = DownloadModels.Undefined DownloadModel = DownloadModels.Undefined
DownloadModelForceApply = .DownloadModelForceApply DownloadModelForceApply = .DownloadModelForceApply
MediaModelAllowNonUserTweets = .MediaModelAllowNonUserTweets MediaModelAllowNonUserTweets = .MediaModelAllowNonUserTweets
@@ -97,6 +98,7 @@ Namespace API.Twitter
If .DownloadModelProfile Then DownloadModel += DownloadModels.Profile If .DownloadModelProfile Then DownloadModel += DownloadModels.Profile
If .DownloadModelSearch Then DownloadModel += DownloadModels.Search If .DownloadModelSearch Then DownloadModel += DownloadModels.Search
If .DownloadModelLikes Then DownloadModel += DownloadModels.Likes If .DownloadModelLikes Then DownloadModel += DownloadModels.Likes
_NameTrue = .UserName
End With End With
End If End If
End Sub End Sub
@@ -454,7 +456,6 @@ Namespace API.Twitter
End If End If
Next Next
'TODO: Twitter: is this line needed?
If ExistsDetected And i = 1 Then Exit For Else ExistsDetected = False If ExistsDetected And i = 1 Then Exit For Else ExistsDetected = False
End If End If
j.Dispose() j.Dispose()

View File

@@ -299,6 +299,24 @@ Namespace API
End If End If
End Get End Get
End Property End Property
Friend ReadOnly Property ContextDownLimit As ToolStripMenuItem()
Get
If Count > 0 Then
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_DOWN_LIMIT).ToArray
Else
Return New ToolStripMenuItem() {}
End If
End Get
End Property
Friend ReadOnly Property ContextDownDate As ToolStripMenuItem()
Get
If Count > 0 Then
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_DOWN_DATE).ToArray
Else
Return New ToolStripMenuItem() {}
End If
End Get
End Property
Friend ReadOnly Property ContextEdit As ToolStripMenuItem() Friend ReadOnly Property ContextEdit As ToolStripMenuItem()
Get Get
If Count > 0 Then If Count > 0 Then

View File

@@ -203,7 +203,7 @@ Namespace API.YouTube
If IsMusic Or DownloadYTVideos Then If IsMusic Or DownloadYTVideos Then
maxDate = Nothing maxDate = Nothing
LastDownloadDateVideos = nDate(LastDownloadDateVideos) LastDownloadDateVideos = nDate(LastDownloadDateVideos)
url = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/{IIf(IsMusic Or IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}" url = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/{IIf(IsMusic Or IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}/videos"
container = YouTubeFunctions.Parse(url, YTUseCookies, Token, pr, __getMinDate(LastDownloadDateVideos), __maxDate,, True) container = YouTubeFunctions.Parse(url, YTUseCookies, Token, pr, __getMinDate(LastDownloadDateVideos), __maxDate,, True)
applySpecFolder.Invoke(IIf(IsMusic, String.Empty, "Videos"), False) applySpecFolder.Invoke(IIf(IsMusic, String.Empty, "Videos"), False)
If fillList.Invoke(LastDownloadDateVideos, False) Then LastDownloadDateVideos = If(maxDate, Now) If fillList.Invoke(LastDownloadDateVideos, False) Then LastDownloadDateVideos = If(maxDate, Now)
@@ -345,6 +345,8 @@ Namespace API.YouTube
If resp.Status = Net.WebExceptionStatus.ConnectFailure And Round < 2 Then If resp.Status = Net.WebExceptionStatus.ConnectFailure And Round < 2 Then
Thread.Sleep(1000) Thread.Sleep(1000)
DownloadCommunity(Cursor, Token, Round + 1) DownloadCommunity(Cursor, Token, Round + 1)
ElseIf resp.StatusCode = Net.HttpStatusCode.NotFound Then
MyMainLOG = $"{ToStringForLog()} {errMsg} (not found)"
Else Else
Throw resp.ErrorException Throw resp.ErrorException
End If End If

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

View File

@@ -379,10 +379,7 @@ Namespace DownloadObjects
Friend Sub New(ByVal x As EContainer) Friend Sub New(ByVal x As EContainer)
Me.New Me.New
Initialization = True Initialization = True
'URGENT: replace this line Mode = x.Value(Name_Mode).FromXML(Of Integer)(Modes.None)
Dim m% = x.Value(Name_Mode).FromXML(Of Integer)(Modes.None)
If m = 1 Or m = 2 Then m = Modes.Specified
Mode = m
Import(x) Import(x)
If Name.IsEmptyString Then Name = "Default" If Name.IsEmptyString Then Name = "Default"
Groups.ListAddList(x.Value(Name_Groups).StringToList(Of String)("|"), LAP.NotContainsOnly) Groups.ListAddList(x.Value(Name_Groups).StringToList(Of String)("|"), LAP.NotContainsOnly)

View File

@@ -230,6 +230,8 @@ Namespace DownloadObjects
PlansWaiter.Invoke(PlanDownloading) PlansWaiter.Invoke(PlanDownloading)
ElseIf .DownloadReady Then ElseIf .DownloadReady Then
.Download() .Download()
If Settings.AutomationScript.Use AndAlso Not Settings.AutomationScript.Value.IsEmptyString AndAlso
(Not .IsManual Or Not Settings.AutomationScript_ExcludeManual) Then ExecuteCommand(Settings.AutomationScript)
End If End If
End With End With
End Sub End Sub

View File

@@ -45,6 +45,8 @@ Namespace DownloadObjects
Me.BTT_LOAD_SESSION_CHOOSE = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_LOAD_SESSION_CHOOSE = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_COPY_TO = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_COPY_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MOVE_TO = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_MOVE_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_COPY_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MOVE_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_FAV = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_LOAD_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_SPEC = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_LOAD_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem()
@@ -61,6 +63,7 @@ Namespace DownloadObjects
Me.BTT_CURR_SESSION_SET = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CURR_SESSION_SET = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MERGE_SESSIONS = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_MERGE_SESSIONS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CLEAR_DAILY = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CLEAR_DAILY = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_RESET_DAILY = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MERGE_FEEDS = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_MERGE_FEEDS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CHECK_ALL = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CHECK_ALL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CHECK_NONE = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CHECK_NONE = New System.Windows.Forms.ToolStripMenuItem()
@@ -72,9 +75,7 @@ Namespace DownloadObjects
Me.BTT_DOWN_SELECTED = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_DOWN_SELECTED = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton() Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
Me.TP_DATA = New System.Windows.Forms.TableLayoutPanel() Me.TP_DATA = New System.Windows.Forms.TableLayoutPanel()
Me.BTT_COPY_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CURR_SESSION_SET_LAST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MOVE_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_RESET_DAILY = New System.Windows.Forms.ToolStripMenuItem()
SEP_1 = New System.Windows.Forms.ToolStripSeparator() SEP_1 = New System.Windows.Forms.ToolStripSeparator()
SEP_2 = New System.Windows.Forms.ToolStripSeparator() SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton() MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
@@ -168,6 +169,11 @@ Namespace DownloadObjects
MENU_LOAD_SEP_8.Name = "MENU_LOAD_SEP_8" MENU_LOAD_SEP_8.Name = "MENU_LOAD_SEP_8"
MENU_LOAD_SEP_8.Size = New System.Drawing.Size(349, 6) MENU_LOAD_SEP_8.Size = New System.Drawing.Size(349, 6)
' '
'MENU_LOAD_SEP_9
'
MENU_LOAD_SEP_9.Name = "MENU_LOAD_SEP_9"
MENU_LOAD_SEP_9.Size = New System.Drawing.Size(349, 6)
'
'ToolbarTOP 'ToolbarTOP
' '
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
@@ -181,7 +187,7 @@ Namespace DownloadObjects
' '
Me.MENU_LOAD_SESSION.AutoToolTip = False Me.MENU_LOAD_SESSION.AutoToolTip = False
Me.MENU_LOAD_SESSION.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image Me.MENU_LOAD_SESSION.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_0, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, MENU_LOAD_SEP_1, Me.BTT_COPY_SPEC_TO, Me.BTT_MOVE_SPEC_TO, MENU_LOAD_SEP_2, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_4, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_5, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE, MENU_LOAD_SEP_6, Me.BTT_CURR_SESSION_SET, Me.BTT_MERGE_SESSIONS, Me.BTT_CLEAR_DAILY, Me.BTT_RESET_DAILY, MENU_LOAD_SEP_7, Me.BTT_MERGE_FEEDS, MENU_LOAD_SEP_8, Me.BTT_CHECK_ALL, Me.BTT_CHECK_NONE, MENU_LOAD_SEP_9, Me.BTT_VIEW_SAVE, Me.BTT_VIEW_LOAD}) Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_0, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, MENU_LOAD_SEP_1, Me.BTT_COPY_SPEC_TO, Me.BTT_MOVE_SPEC_TO, MENU_LOAD_SEP_2, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_4, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_5, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE, MENU_LOAD_SEP_6, Me.BTT_CURR_SESSION_SET, Me.BTT_CURR_SESSION_SET_LAST, Me.BTT_MERGE_SESSIONS, Me.BTT_CLEAR_DAILY, Me.BTT_RESET_DAILY, MENU_LOAD_SEP_7, Me.BTT_MERGE_FEEDS, MENU_LOAD_SEP_8, Me.BTT_CHECK_ALL, Me.BTT_CHECK_NONE, MENU_LOAD_SEP_9, Me.BTT_VIEW_SAVE, Me.BTT_VIEW_LOAD})
Me.MENU_LOAD_SESSION.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24 Me.MENU_LOAD_SESSION.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.MENU_LOAD_SESSION.ImageTransparentColor = System.Drawing.Color.Magenta Me.MENU_LOAD_SESSION.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_LOAD_SESSION.Name = "MENU_LOAD_SESSION" Me.MENU_LOAD_SESSION.Name = "MENU_LOAD_SESSION"
@@ -223,6 +229,24 @@ Namespace DownloadObjects
Me.BTT_MOVE_TO.Size = New System.Drawing.Size(352, 22) Me.BTT_MOVE_TO.Size = New System.Drawing.Size(352, 22)
Me.BTT_MOVE_TO.Text = "Move checked to..." Me.BTT_MOVE_TO.Text = "Move checked to..."
' '
'BTT_COPY_SPEC_TO
'
Me.BTT_COPY_SPEC_TO.AutoToolTip = True
Me.BTT_COPY_SPEC_TO.Image = Global.SCrawler.My.Resources.Resources.PastePic_32
Me.BTT_COPY_SPEC_TO.Name = "BTT_COPY_SPEC_TO"
Me.BTT_COPY_SPEC_TO.Size = New System.Drawing.Size(352, 22)
Me.BTT_COPY_SPEC_TO.Text = "Copy feed/session files to..."
Me.BTT_COPY_SPEC_TO.ToolTipText = "Copy all the files of the loaded feed/session to..."
'
'BTT_MOVE_SPEC_TO
'
Me.BTT_MOVE_SPEC_TO.AutoToolTip = True
Me.BTT_MOVE_SPEC_TO.Image = Global.SCrawler.My.Resources.Resources.CutPic_48
Me.BTT_MOVE_SPEC_TO.Name = "BTT_MOVE_SPEC_TO"
Me.BTT_MOVE_SPEC_TO.Size = New System.Drawing.Size(352, 22)
Me.BTT_MOVE_SPEC_TO.Text = "Move feed/session files to..."
Me.BTT_MOVE_SPEC_TO.ToolTipText = "Move all the files of the loaded feed/session to..."
'
'BTT_LOAD_FAV 'BTT_LOAD_FAV
' '
Me.BTT_LOAD_FAV.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32 Me.BTT_LOAD_FAV.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
@@ -342,6 +366,15 @@ Namespace DownloadObjects
Me.BTT_CLEAR_DAILY.Text = "Clear session" Me.BTT_CLEAR_DAILY.Text = "Clear session"
Me.BTT_CLEAR_DAILY.ToolTipText = "Clear current session" Me.BTT_CLEAR_DAILY.ToolTipText = "Clear current session"
' '
'BTT_RESET_DAILY
'
Me.BTT_RESET_DAILY.AutoToolTip = True
Me.BTT_RESET_DAILY.Image = Global.SCrawler.My.Resources.Resources.RefreshPic_24
Me.BTT_RESET_DAILY.Name = "BTT_RESET_DAILY"
Me.BTT_RESET_DAILY.Size = New System.Drawing.Size(352, 22)
Me.BTT_RESET_DAILY.Text = "Reset current session"
Me.BTT_RESET_DAILY.ToolTipText = "A new file will be created for the current session"
'
'BTT_MERGE_FEEDS 'BTT_MERGE_FEEDS
' '
Me.BTT_MERGE_FEEDS.AutoToolTip = True Me.BTT_MERGE_FEEDS.AutoToolTip = True
@@ -443,37 +476,12 @@ Namespace DownloadObjects
Me.TP_DATA.Size = New System.Drawing.Size(484, 436) Me.TP_DATA.Size = New System.Drawing.Size(484, 436)
Me.TP_DATA.TabIndex = 1 Me.TP_DATA.TabIndex = 1
' '
'MENU_LOAD_SEP_9 'BTT_CURR_SESSION_SET_LAST
' '
MENU_LOAD_SEP_9.Name = "MENU_LOAD_SEP_9" Me.BTT_CURR_SESSION_SET_LAST.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
MENU_LOAD_SEP_9.Size = New System.Drawing.Size(349, 6) Me.BTT_CURR_SESSION_SET_LAST.Name = "BTT_CURR_SESSION_SET_LAST"
' Me.BTT_CURR_SESSION_SET_LAST.Size = New System.Drawing.Size(352, 22)
'BTT_COPY_SPEC_TO Me.BTT_CURR_SESSION_SET_LAST.Text = "Set last download session as current session"
'
Me.BTT_COPY_SPEC_TO.AutoToolTip = True
Me.BTT_COPY_SPEC_TO.Image = Global.SCrawler.My.Resources.Resources.PastePic_32
Me.BTT_COPY_SPEC_TO.Name = "BTT_COPY_SPEC_TO"
Me.BTT_COPY_SPEC_TO.Size = New System.Drawing.Size(352, 22)
Me.BTT_COPY_SPEC_TO.Text = "Copy feed/session files to..."
Me.BTT_COPY_SPEC_TO.ToolTipText = "Copy all the files of the loaded feed/session to..."
'
'BTT_MOVE_SPEC_TO
'
Me.BTT_MOVE_SPEC_TO.AutoToolTip = True
Me.BTT_MOVE_SPEC_TO.Image = Global.SCrawler.My.Resources.Resources.CutPic_48
Me.BTT_MOVE_SPEC_TO.Name = "BTT_MOVE_SPEC_TO"
Me.BTT_MOVE_SPEC_TO.Size = New System.Drawing.Size(352, 22)
Me.BTT_MOVE_SPEC_TO.Text = "Move feed/session files to..."
Me.BTT_MOVE_SPEC_TO.ToolTipText = "Move all the files of the loaded feed/session to..."
'
'BTT_RESET_DAILY
'
Me.BTT_RESET_DAILY.AutoToolTip = True
Me.BTT_RESET_DAILY.Image = Global.SCrawler.My.Resources.Resources.RefreshPic_24
Me.BTT_RESET_DAILY.Name = "BTT_RESET_DAILY"
Me.BTT_RESET_DAILY.Size = New System.Drawing.Size(352, 22)
Me.BTT_RESET_DAILY.Text = "Reset current session"
Me.BTT_RESET_DAILY.ToolTipText = "A new file will be created for the current session"
' '
'DownloadFeedForm 'DownloadFeedForm
' '
@@ -534,5 +542,6 @@ Namespace DownloadObjects
Private WithEvents BTT_COPY_SPEC_TO As ToolStripMenuItem Private WithEvents BTT_COPY_SPEC_TO As ToolStripMenuItem
Private WithEvents BTT_MOVE_SPEC_TO As ToolStripMenuItem Private WithEvents BTT_MOVE_SPEC_TO As ToolStripMenuItem
Private WithEvents BTT_RESET_DAILY As ToolStripMenuItem Private WithEvents BTT_RESET_DAILY As ToolStripMenuItem
Private WithEvents BTT_CURR_SESSION_SET_LAST As ToolStripMenuItem
End Class End Class
End Namespace End Namespace

View File

@@ -162,10 +162,10 @@
<metadata name="MENU_LOAD_SEP_8.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="MENU_LOAD_SEP_8.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="MENU_LOAD_SEP_9.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="MENU_LOAD_SEP_9.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root> </root>

View File

@@ -190,7 +190,6 @@ Namespace DownloadObjects
DataList.Clear() DataList.Clear()
End Sub End Sub
Private Sub DownloadFeedForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown Private Sub DownloadFeedForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
'If e.KeyCode = Keys.F5 Then RefillList() : e.Handled = True
If Not e.Handled Then If Not e.Handled Then
Dim b As Boolean = False Dim b As Boolean = False
If e = GoToButton Then If e = GoToButton Then
@@ -207,6 +206,8 @@ Namespace DownloadObjects
Case Keys.Down, Keys.Right, Keys.PageDown : changePage = 1 Case Keys.Down, Keys.Right, Keys.PageDown : changePage = 1
Case Keys.Home : gotoHome = True Case Keys.Home : gotoHome = True
Case Keys.End : gotoHome = False Case Keys.End : gotoHome = False
Case Keys.Escape : If Settings.FeedEscToClose Then Close()
Case Else : If e.Control And e.KeyCode = Keys.W Then Close()
End Select End Select
If changePage.HasValue Then If changePage.HasValue Then
b = True b = True
@@ -515,17 +516,21 @@ Namespace DownloadObjects
f = Downloader.FilesSessionActual(False) f = Downloader.FilesSessionActual(False)
End If End If
If f.Exists Then If f.Exists Then
If SelectedMode >= 0 Then If GetSessionFile Then
If SelectedMode = FeedModes.Saved Then LoadedSessionName = f.Name If Not Downloader.FilesSessionActual(False) = f Then SessionFile = f
FeedChangeMode(SelectedMode) Else
If SelectedMode >= 0 Then
If SelectedMode = FeedModes.Saved Then LoadedSessionName = f.Name
FeedChangeMode(SelectedMode)
End If
DataList.Clear()
x = New XmlFile(f,, False) With {.AllowSameNames = True, .XmlReadOnly = True}
x.LoadData()
If x.Count > 0 Then DataList.ListAddList(x, lcr)
x.Dispose()
CleanDataList()
RefillList(False, False)
End If End If
DataList.Clear()
x = New XmlFile(f,, False) With {.AllowSameNames = True, .XmlReadOnly = True}
x.LoadData()
If x.Count > 0 Then DataList.ListAddList(x, lcr)
x.Dispose()
CleanDataList()
RefillList(False, False)
End If End If
Else Else
m.Text = "Saved sessions not found" m.Text = "Saved sessions not found"
@@ -537,6 +542,7 @@ Namespace DownloadObjects
End Try End Try
End Sub End Sub
#End Region #End Region
#Region "Move/Copy"
Private Sub BTT_COPY_MOVE_TO_Click(sender As Object, e As EventArgs) Handles BTT_COPY_TO.Click, BTT_MOVE_TO.Click Private Sub BTT_COPY_MOVE_TO_Click(sender As Object, e As EventArgs) Handles BTT_COPY_TO.Click, BTT_MOVE_TO.Click
MoveCopyFiles(True, sender, Nothing, Nothing) MoveCopyFiles(True, sender, Nothing, Nothing)
End Sub End Sub
@@ -545,7 +551,7 @@ Namespace DownloadObjects
End Sub End Sub
Private Function MoveCopyFiles(ByVal IsInternal As Boolean, ByVal Sender As Object, ByVal MCTOptions As FeedMoveCopyTo, Private Function MoveCopyFiles(ByVal IsInternal As Boolean, ByVal Sender As Object, ByVal MCTOptions As FeedMoveCopyTo,
ByVal FeedMediaData As FeedMedia, Optional ByVal GetChecked As Boolean = True) As Boolean ByVal FeedMediaData As FeedMedia, Optional ByVal GetChecked As Boolean = True) As Boolean
Const MsgTitle$ = "Copy/Move checked files" Dim MsgTitle$ = "Copy/Move checked files"
Try Try
Dim isCopy As Boolean = Not Sender Is Nothing AndAlso (Sender Is BTT_COPY_TO OrElse Sender Is BTT_COPY_SPEC_TO) Dim isCopy As Boolean = Not Sender Is Nothing AndAlso (Sender Is BTT_COPY_TO OrElse Sender Is BTT_COPY_SPEC_TO)
Dim moveOptions As FeedMoveCopyTo = Nothing Dim moveOptions As FeedMoveCopyTo = Nothing
@@ -553,6 +559,7 @@ Namespace DownloadObjects
Dim data As IEnumerable(Of UserMediaD) = Nothing Dim data As IEnumerable(Of UserMediaD) = Nothing
Dim dd As UserMediaD Dim dd As UserMediaD
Dim __user As UserInfo Dim __user As UserInfo
Dim __isSavedPosts As Boolean
Dim data_files As IEnumerable(Of SFile) = Nothing Dim data_files As IEnumerable(Of SFile) = Nothing
Dim new_files As New List(Of SFile) Dim new_files As New List(Of SFile)
Dim mm As UserMediaD Dim mm As UserMediaD
@@ -568,6 +575,7 @@ Namespace DownloadObjects
Dim sesFilesReplaced As Boolean = False Dim sesFilesReplaced As Boolean = False
Dim filesReplace As New List(Of KeyValuePair(Of SFile, SFile)) Dim filesReplace As New List(Of KeyValuePair(Of SFile, SFile))
Dim updateFileLocations As Boolean = Settings.FeedMoveCopyUpdateFileLocationOnMove Dim updateFileLocations As Boolean = Settings.FeedMoveCopyUpdateFileLocationOnMove
Dim postUrl$
Dim result As Boolean = False Dim result As Boolean = False
If FeedMediaData Is Nothing Then If FeedMediaData Is Nothing Then
@@ -584,7 +592,18 @@ Namespace DownloadObjects
data = {FeedMediaData.Media} data = {FeedMediaData.Media}
data_files = {FeedMediaData.File} data_files = {FeedMediaData.File}
End If End If
MsgTitle = $"{IIf(isCopy, "Copy", "Move")} {IIf(Not FeedMediaData Is Nothing Or GetChecked, "checked", "ALL")} files"
If data.ListExists Then If data.ListExists Then
If (FeedMediaData Is Nothing And Not GetChecked And Not isCopy) AndAlso
MsgBoxE({$"YOU ARE TRYING TO MOVE ALL FEED/SESSION DATA.{vbCr}EVERY FILE WILL BE MOVED, NOT JUST THE SELECTED ONES.", MsgTitle},
vbExclamation,,, {"Process", "Cancel"}) = 1 Then
ShowOperationCanceledMsg(MsgTitle)
Return False
End If
If MCTOptions.Destination.IsEmptyString Then If MCTOptions.Destination.IsEmptyString Then
Using f As New FeedCopyToForm(data_files, isCopy) Using f As New FeedCopyToForm(data_files, isCopy)
f.ShowDialog() f.ShowDialog()
@@ -671,8 +690,13 @@ Namespace DownloadObjects
__user = mm.UserInfo __user = mm.UserInfo
mm_data = mm.Data mm_data = mm.Data
mm_data.File = df mm_data.File = df
mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) With {.IsSavedPosts = mm.IsSavedPosts} __isSavedPosts = mm.IsSavedPosts And moveOptions.ReplaceUserProfile_Profile Is Nothing
If moveOptions.ReplaceUserProfile_Profile Is Nothing And mm.IsSavedPosts Then mm.UserInfo = __user postUrl = mm.PostUrl(True)
mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) With {
.IsSavedPosts = __isSavedPosts,
.PostUrl = postUrl
}
If __isSavedPosts Then mm.UserInfo = __user
Downloader.Files(indx) = mm Downloader.Files(indx) = mm
downloaderFilesUpdated = True downloaderFilesUpdated = True
End If End If
@@ -701,8 +725,13 @@ Namespace DownloadObjects
__user = mm.UserInfo __user = mm.UserInfo
mm_data = mm.Data mm_data = mm.Data
mm_data.File = df mm_data.File = df
mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) With {.IsSavedPosts = mm.IsSavedPosts} __isSavedPosts = mm.IsSavedPosts And moveOptions.ReplaceUserProfile_Profile Is Nothing
If moveOptions.ReplaceUserProfile_Profile Is Nothing And mm.IsSavedPosts Then mm.UserInfo = __user postUrl = mm.PostUrl(True)
mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) With {
.IsSavedPosts = __isSavedPosts,
.PostUrl = postUrl
}
If __isSavedPosts Then mm.UserInfo = __user
sessionData(indx) = mm sessionData(indx) = mm
sesFilesReplaced = True sesFilesReplaced = True
If DataList.Count > 0 Then If DataList.Count > 0 Then
@@ -741,6 +770,7 @@ Namespace DownloadObjects
Settings.Feeds.UpdateWhereDataReplaced() Settings.Feeds.UpdateWhereDataReplaced()
End Try End Try
End Function End Function
#End Region
#Region "Load fav, spec" #Region "Load fav, spec"
Private Sub BTT_LOAD_FAV_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_FAV.Click Private Sub BTT_LOAD_FAV_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_FAV.Click
FeedChangeMode(FeedModes.Special, {FeedSpecial.FavoriteName}) FeedChangeMode(FeedModes.Special, {FeedSpecial.FavoriteName})
@@ -922,10 +952,10 @@ Namespace DownloadObjects
End Sub End Sub
#End Region #End Region
#Region "Sessions set, merge, clear" #Region "Sessions set, merge, clear"
Private Sub BTT_CURR_SESSION_SET_Click(sender As Object, e As EventArgs) Handles BTT_CURR_SESSION_SET.Click Private Sub BTT_CURR_SESSION_SET_Click(sender As Object, e As EventArgs) Handles BTT_CURR_SESSION_SET.Click, BTT_CURR_SESSION_SET_LAST.Click
Try Try
Dim f As SFile = Nothing Dim f As SFile = Nothing
SessionChooser(False,,,, True, f) SessionChooser(sender Is BTT_CURR_SESSION_SET_LAST,,,, True, f)
If Not f.IsEmptyString AndAlso f.Exists Then If Not f.IsEmptyString AndAlso f.Exists Then
Downloader.FilesLoadLastSession(f) Downloader.FilesLoadLastSession(f)
FeedChangeMode(FeedModes.Current) FeedChangeMode(FeedModes.Current)
@@ -1284,32 +1314,36 @@ Namespace DownloadObjects
End Try End Try
End Sub End Sub
Private Sub RefillAfterDelete() Private Sub RefillAfterDelete()
With MyRange Try
Dim indx% = .CurrentIndex With MyRange
Dim indxChanged As Boolean = False Dim indx% = .CurrentIndex
.HandlersSuspended = True Dim indxChanged As Boolean = False
.Update() .HandlersSuspended = True
If .Count > 0 Then .Update()
If indx.ValueBetween(0, .Count - 1) Then If .Count > 0 Then
.CurrentIndex = indx If indx.ValueBetween(0, .Count - 1) Then
ElseIf (indx - 1).ValueBetween(0, .Count - 1) Then .CurrentIndex = indx
.CurrentIndex = indx - 1 ElseIf (indx - 1).ValueBetween(0, .Count - 1) Then
indxChanged = True .CurrentIndex = indx - 1
Else indxChanged = True
.CurrentIndex = .Count - 1 Else
indxChanged = Not indx = .CurrentIndex .CurrentIndex = .Count - 1
indxChanged = Not indx = .CurrentIndex
End If
.UpdateControls()
.HandlersSuspended = False
If Not indxChanged Then LatestScrollValueDisabled = True
DirectCast(MyRange.Switcher, RangeSwitcher(Of UserMediaD)).PerformIndexChanged()
If Not indxChanged Then
LatestScrollValueDisabled = False
SetScrollValue(True)
End If
End If End If
.UpdateControls()
.HandlersSuspended = False .HandlersSuspended = False
If Not indxChanged Then LatestScrollValueDisabled = True End With
DirectCast(MyRange.Switcher, RangeSwitcher(Of UserMediaD)).PerformIndexChanged() Catch ex As Exception
If Not indxChanged Then ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadFeedForm.RefillAfterDelete]")
LatestScrollValueDisabled = False End Try
SetScrollValue(True)
End If
End If
.HandlersSuspended = False
End With
End Sub End Sub
#End Region #End Region
#Region "Range" #Region "Range"

View File

@@ -27,7 +27,6 @@ Namespace DownloadObjects
Dim TP_LBL As System.Windows.Forms.TableLayoutPanel Dim TP_LBL As System.Windows.Forms.TableLayoutPanel
Dim CONTEXT_SEP_3 As System.Windows.Forms.ToolStripSeparator Dim CONTEXT_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim CONTEXT_SEP_4 As System.Windows.Forms.ToolStripSeparator Dim CONTEXT_SEP_4 As System.Windows.Forms.ToolStripSeparator
Me.CONTEXT_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
Me.CH_CHECKED = New System.Windows.Forms.CheckBox() Me.CH_CHECKED = New System.Windows.Forms.CheckBox()
Me.LBL_INFO = New System.Windows.Forms.Label() Me.LBL_INFO = New System.Windows.Forms.Label()
Me.CONTEXT_DATA = New System.Windows.Forms.ContextMenuStrip(Me.components) Me.CONTEXT_DATA = New System.Windows.Forms.ContextMenuStrip(Me.components)
@@ -37,6 +36,7 @@ Namespace DownloadObjects
Me.BTT_CONTEXT_OPEN_USER = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CONTEXT_OPEN_USER = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_OPEN_USER_URL = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CONTEXT_OPEN_USER_URL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_OPEN_USER_POST = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CONTEXT_OPEN_USER_POST = New System.Windows.Forms.ToolStripMenuItem()
Me.CONTEXT_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_COPY_TO = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_COPY_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MOVE_TO = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_MOVE_TO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem()
@@ -52,6 +52,7 @@ Namespace DownloadObjects
Me.ICON_SITE = New System.Windows.Forms.PictureBox() Me.ICON_SITE = New System.Windows.Forms.PictureBox()
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel() Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
Me.LBL_TITLE = New System.Windows.Forms.Label() Me.LBL_TITLE = New System.Windows.Forms.Label()
Me.BTT_CONTEXT_OPEN_FILE_FOLDER = New System.Windows.Forms.ToolStripMenuItem()
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator() CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
TP_LBL = New System.Windows.Forms.TableLayoutPanel() TP_LBL = New System.Windows.Forms.TableLayoutPanel()
CONTEXT_SEP_3 = New System.Windows.Forms.ToolStripSeparator() CONTEXT_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
@@ -67,11 +68,6 @@ Namespace DownloadObjects
CONTEXT_SEP_1.Name = "CONTEXT_SEP_1" CONTEXT_SEP_1.Name = "CONTEXT_SEP_1"
CONTEXT_SEP_1.Size = New System.Drawing.Size(302, 6) CONTEXT_SEP_1.Size = New System.Drawing.Size(302, 6)
' '
'CONTEXT_SEP_2
'
Me.CONTEXT_SEP_2.Name = "CONTEXT_SEP_2"
Me.CONTEXT_SEP_2.Size = New System.Drawing.Size(302, 6)
'
'TP_LBL 'TP_LBL
' '
TP_LBL.ColumnCount = 3 TP_LBL.ColumnCount = 3
@@ -114,9 +110,9 @@ Namespace DownloadObjects
' '
'CONTEXT_DATA 'CONTEXT_DATA
' '
Me.CONTEXT_DATA.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.CONTEXT_SEP_0, Me.BTT_CONTEXT_OPEN_MEDIA, Me.BTT_CONTEXT_OPEN_USER, CONTEXT_SEP_1, Me.BTT_CONTEXT_OPEN_USER_URL, Me.BTT_CONTEXT_OPEN_USER_POST, Me.CONTEXT_SEP_2, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, CONTEXT_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_FAV, Me.BTT_FEED_REMOVE_SPEC, CONTEXT_SEP_4, Me.BTT_CONTEXT_FIND_USER, Me.BTT_CONTEXT_INFO, Me.CONTEXT_SEP_5, Me.BTT_CONTEXT_DELETE}) Me.CONTEXT_DATA.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.CONTEXT_SEP_0, Me.BTT_CONTEXT_OPEN_MEDIA, Me.BTT_CONTEXT_OPEN_USER, Me.BTT_CONTEXT_OPEN_FILE_FOLDER, CONTEXT_SEP_1, Me.BTT_CONTEXT_OPEN_USER_URL, Me.BTT_CONTEXT_OPEN_USER_POST, Me.CONTEXT_SEP_2, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, CONTEXT_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_FAV, Me.BTT_FEED_REMOVE_SPEC, CONTEXT_SEP_4, Me.BTT_CONTEXT_FIND_USER, Me.BTT_CONTEXT_INFO, Me.CONTEXT_SEP_5, Me.BTT_CONTEXT_DELETE})
Me.CONTEXT_DATA.Name = "CONTEXT_PIC" Me.CONTEXT_DATA.Name = "CONTEXT_PIC"
Me.CONTEXT_DATA.Size = New System.Drawing.Size(306, 414) Me.CONTEXT_DATA.Size = New System.Drawing.Size(306, 436)
' '
'BTT_CONTEXT_DOWN 'BTT_CONTEXT_DOWN
' '
@@ -160,6 +156,11 @@ Namespace DownloadObjects
Me.BTT_CONTEXT_OPEN_USER_POST.Size = New System.Drawing.Size(305, 22) Me.BTT_CONTEXT_OPEN_USER_POST.Size = New System.Drawing.Size(305, 22)
Me.BTT_CONTEXT_OPEN_USER_POST.Text = "Open post" Me.BTT_CONTEXT_OPEN_USER_POST.Text = "Open post"
' '
'CONTEXT_SEP_2
'
Me.CONTEXT_SEP_2.Name = "CONTEXT_SEP_2"
Me.CONTEXT_SEP_2.Size = New System.Drawing.Size(302, 6)
'
'BTT_COPY_TO 'BTT_COPY_TO
' '
Me.BTT_COPY_TO.Image = Global.SCrawler.My.Resources.Resources.PastePic_32 Me.BTT_COPY_TO.Image = Global.SCrawler.My.Resources.Resources.PastePic_32
@@ -289,6 +290,13 @@ Namespace DownloadObjects
Me.LBL_TITLE.Size = New System.Drawing.Size(140, 25) Me.LBL_TITLE.Size = New System.Drawing.Size(140, 25)
Me.LBL_TITLE.TabIndex = 1 Me.LBL_TITLE.TabIndex = 1
' '
'BTT_CONTEXT_OPEN_FILE_FOLDER
'
Me.BTT_CONTEXT_OPEN_FILE_FOLDER.Image = Global.SCrawler.My.Resources.Resources.FolderPic_32
Me.BTT_CONTEXT_OPEN_FILE_FOLDER.Name = "BTT_CONTEXT_OPEN_FILE_FOLDER"
Me.BTT_CONTEXT_OPEN_FILE_FOLDER.Size = New System.Drawing.Size(305, 22)
Me.BTT_CONTEXT_OPEN_FILE_FOLDER.Text = "Open file folder"
'
'FeedMedia 'FeedMedia
' '
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
@@ -335,5 +343,6 @@ Namespace DownloadObjects
Private WithEvents BTT_MOVE_TO As ToolStripMenuItem Private WithEvents BTT_MOVE_TO As ToolStripMenuItem
Private WithEvents CONTEXT_SEP_5 As ToolStripSeparator Private WithEvents CONTEXT_SEP_5 As ToolStripSeparator
Private WithEvents CONTEXT_SEP_2 As ToolStripSeparator Private WithEvents CONTEXT_SEP_2 As ToolStripSeparator
Private WithEvents BTT_CONTEXT_OPEN_FILE_FOLDER As ToolStripMenuItem
End Class End Class
End Namespace End Namespace

View File

@@ -178,6 +178,7 @@ Namespace DownloadObjects
BTT_CONTEXT_DOWN.Visible = True BTT_CONTEXT_DOWN.Visible = True
CONTEXT_SEP_0.Visible = True CONTEXT_SEP_0.Visible = True
BTT_CONTEXT_OPEN_USER.Visible = False BTT_CONTEXT_OPEN_USER.Visible = False
BTT_CONTEXT_OPEN_FILE_FOLDER.Visible = False
CONTEXT_SEP_5.Visible = False CONTEXT_SEP_5.Visible = False
BTT_CONTEXT_DELETE.Visible = False BTT_CONTEXT_DELETE.Visible = False
@@ -416,8 +417,12 @@ Namespace DownloadObjects
End Sub End Sub
#End Region #End Region
#Region "Open media, folder" #Region "Open media, folder"
Private Sub BTT_CONTEXT_OPEN_MEDIA_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_MEDIA.Click Private Sub BTT_CONTEXT_OPEN_MEDIA_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_MEDIA.Click, BTT_CONTEXT_OPEN_FILE_FOLDER.Click
File.Open() If Not sender Is Nothing AndAlso sender Is BTT_CONTEXT_OPEN_FILE_FOLDER Then
GlobalOpenPath(File)
Else
File.Open()
End If
End Sub End Sub
Private Sub BTT_CONTEXT_OPEN_USER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER.Click Private Sub BTT_CONTEXT_OPEN_USER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER.Click
If Not UserKey.IsEmptyString Then If Not UserKey.IsEmptyString Then
@@ -455,6 +460,8 @@ Namespace DownloadObjects
Dim url$ = String.Empty Dim url$ = String.Empty
If IsSubscription Then If IsSubscription Then
url = Post.URL_BASE url = Post.URL_BASE
ElseIf Not Media.PostUrl.IsEmptyString Then
url = Media.PostUrl
Else Else
If Not UserKey.IsEmptyString And Not Post.Post.ID.IsEmptyString Then If Not UserKey.IsEmptyString And Not Post.Post.ID.IsEmptyString Then
Dim u As IUserData Dim u As IUserData

View File

@@ -157,6 +157,7 @@ Namespace DownloadObjects
Else Else
user = Item.User user = Item.User
End If End If
If isSaved Then isSaved = Item.UserInfo.Equals(DirectCast(user, UserDataBase).User)
If Not If(user?.IsSubscription, False) Then If Not If(user?.IsSubscription, False) Then
Item = New UserMediaD(data, user, Item.Session, Item.Date) With {.IsSavedPosts = isSaved} Item = New UserMediaD(data, user, Item.Session, Item.Date) With {.IsSavedPosts = isSaved}
Result = True Result = True
@@ -176,9 +177,10 @@ Namespace DownloadObjects
Dim m As UserMediaD = Items(indx) Dim m As UserMediaD = Items(indx)
Dim mm As UserMedia = m.Data Dim mm As UserMedia = m.Data
Dim user As UserInfo = m.UserInfo Dim user As UserInfo = m.UserInfo
Dim __isSavedPosts As Boolean = m.IsSavedPosts And MCTOptions.ReplaceUserProfile_Profile Is Nothing
mm.File = NewFile mm.File = NewFile
m = New UserMediaD(mm, If(MCTOptions.ReplaceUserProfile_Profile, m.User), m.Session, m.Date) With {.IsSavedPosts = m.IsSavedPosts} m = New UserMediaD(mm, If(MCTOptions.ReplaceUserProfile_Profile, m.User), m.Session, m.Date) With {.IsSavedPosts = __isSavedPosts}
If MCTOptions.ReplaceUserProfile_Profile Is Nothing And m.IsSavedPosts Then m.UserInfo = user If __isSavedPosts Then m.UserInfo = user
Items(indx) = m Items(indx) = m
_FilesUpdated = True _FilesUpdated = True
End If End If
@@ -193,6 +195,7 @@ Namespace DownloadObjects
#Region "Add" #Region "Add"
Friend Overloads Function Add(ByVal Item As UserMediaD, Optional ByVal AutoSave As Boolean = True) As Boolean Friend Overloads Function Add(ByVal Item As UserMediaD, Optional ByVal AutoSave As Boolean = True) As Boolean
If Not Items.Contains(Item) Then If Not Items.Contains(Item) Then
Item.PostUrl = Item.PostUrl(True)
Items.Add(Item) Items.Add(Item)
If AutoSave Then Save() If AutoSave Then Save()
Return True Return True
@@ -233,7 +236,65 @@ Namespace DownloadObjects
Friend Function RemoveNotExist(ByVal p As Predicate(Of UserMediaD)) As Integer Friend Function RemoveNotExist(ByVal p As Predicate(Of UserMediaD)) As Integer
If Count > 0 And Not _NotExistRemoved Then If Count > 0 And Not _NotExistRemoved Then
_NotExistRemoved = True _NotExistRemoved = True
Dim ri% = Items.RemoveAll(p) Dim ri% = 0
If Settings.FeedSpecialSearchForMissing Then
Dim i% = -1
Dim d As UserMediaD = Nothing
Dim m As UserMedia
Dim f As SFile = Nothing
Dim ff As SFile
Dim postUrl$ = String.Empty
Dim user As IUserData
Dim processRemove As Boolean
Dim userArr As New List(Of IUserData)
Dim updateUser As Func(Of IUserData, Boolean) =
Function(ByVal replaceUser As IUserData) As Boolean
If f.Exists(SFO.Path, False) Then
ff = SFile.GetFiles(f, d.Data.File.File, IO.SearchOption.AllDirectories, EDP.ReturnValue).FirstOrDefault
If Not ff.IsEmptyString Then
m = d.Data
m.File = ff
d = New UserMediaD(m, If(replaceUser, d.User), d.Session, d.Date) With {
.IsSavedPosts = If(replaceUser Is Nothing, d.IsSavedPosts, DirectCast(replaceUser, UserDataBase).IsSavedPosts),
.PostUrl = postUrl
}
Items(i) = d
ri += 1
processRemove = False
Return True
End If
End If
Return False
End Function
For i = Count - 1 To 0 Step -1
If p.Invoke(Items(i)) Then
d = Items(i)
postUrl = d.PostUrl(True)
f = Nothing
ff = Nothing
processRemove = True
f = If(d.User?.File, New SFile).IfNullOrEmpty(d.UserInfo.File).CutPath
If updateUser(Nothing) Then Continue For
If Settings.FeedSpecialSearchForMissing_Deep Then
If userArr.Count = 0 Then userArr.ListAddList(Settings.GetUsers(Function(u) True))
If userArr.Count > 0 Then
For Each user In userArr
f = user.File.CutPath
If updateUser(user) Then Exit For
Next
End If
End If
If processRemove Then Items.RemoveAt(i) : ri += 1
End If
Next
Else
ri = Items.RemoveAll(p)
End If
If ri > 0 Then Save() If ri > 0 Then Save()
Return ri Return ri
Else Else

View File

@@ -36,6 +36,7 @@ Namespace DownloadObjects
Private Const Name_Session As String = "Session" Private Const Name_Session As String = "Session"
Private Const Name_File As String = "File" Private Const Name_File As String = "File"
Private Const Name_IsSavedPosts As String = "IsSavedPosts" Private Const Name_IsSavedPosts As String = "IsSavedPosts"
Private Const Name_PostUrl As String = "PostUrl"
#End Region #End Region
Friend ReadOnly User As IUserData Friend ReadOnly User As IUserData
Friend ReadOnly Data As UserMedia Friend ReadOnly Data As UserMedia
@@ -43,6 +44,48 @@ Namespace DownloadObjects
Friend ReadOnly [Date] As Date Friend ReadOnly [Date] As Date
Friend Session As Integer Friend Session As Integer
Friend IsSavedPosts As Boolean Friend IsSavedPosts As Boolean
Private _PostUrl As String
Friend Property PostUrl(Optional ByVal Generate As Boolean = False) As String
Get
Try
If Not _PostUrl.IsEmptyString Then
Return _PostUrl
ElseIf Generate Then
Dim url$ = String.Empty
With UserInfo
If Not .Plugin.IfNullOrEmpty(.Site).IsEmptyString And Not .Name.IsEmptyString And Not Data.Post.ID.IsEmptyString Then
Dim u As IUserData
If IsSavedPosts Then
If Not .Plugin.IsEmptyString Then
Dim host As SettingsHostCollection = Settings(.Plugin)
If Not host Is Nothing Then
u = host.Default.GetInstance(Download.SavedPosts, UserInfo, False, False)
If Not u Is Nothing AndAlso Not u.HOST Is Nothing Then
With DirectCast(u, UserDataBase)
.IsSavedPosts = True
.HostStatic = True
End With
Try : url = u.HOST.Source.GetUserPostUrl(u, Data) : Catch : End Try
u.Dispose()
End If
End If
End If
Else
u = Settings.GetUser(UserInfo)
If Not u Is Nothing Then url = UserDataBase.GetPostUrl(u, Data)
End If
End If
End With
Return url
End If
Catch
End Try
Return String.Empty
End Get
Set(ByVal _PostUrl As String)
Me._PostUrl = _PostUrl
End Set
End Property
Friend Sub New(ByVal Data As UserMedia, ByVal User As IUserData, ByVal Session As Integer) Friend Sub New(ByVal Data As UserMedia, ByVal User As IUserData, ByVal Session As Integer)
Me.Data = Data Me.Data = Data
Me.User = User Me.User = User
@@ -78,6 +121,7 @@ Namespace DownloadObjects
Data = New UserMedia(e(Name_Media), User) Data = New UserMedia(e(Name_Media), User)
[Date] = AConvert(Of Date)(e.Value(Name_Date), DateTimeDefaultProvider, Now) [Date] = AConvert(Of Date)(e.Value(Name_Date), DateTimeDefaultProvider, Now)
Session = e.Value(Name_Session).FromXML(Of Integer)(0) Session = e.Value(Name_Session).FromXML(Of Integer)(0)
_PostUrl = e.Value(Name_PostUrl)
Dim f As SFile = e.Value(Name_File) Dim f As SFile = e.Value(Name_File)
If f.Exists Then Data.File = f If f.Exists Then Data.File = f
End If End If
@@ -106,7 +150,8 @@ Namespace DownloadObjects
New EContainer(Name_Date, AConvert(Of String)([Date], DateTimeDefaultProvider, String.Empty)), New EContainer(Name_Date, AConvert(Of String)([Date], DateTimeDefaultProvider, String.Empty)),
New EContainer(Name_Session, Session), New EContainer(Name_Session, Session),
New EContainer(Name_File, Data.File), New EContainer(Name_File, Data.File),
New EContainer(Name_IsSavedPosts, IsSavedPosts.BoolToInteger)}, New EContainer(Name_IsSavedPosts, IsSavedPosts.BoolToInteger),
New EContainer(Name_PostUrl, _PostUrl)},
If(IsSavedPosts, UserInfo.ToEContainer, If(Not User Is Nothing, DirectCast(User, UserDataBase).User.ToEContainer, Nothing)), LAP.IgnoreICopier) If(IsSavedPosts, UserInfo.ToEContainer, If(Not User Is Nothing, DirectCast(User, UserDataBase).User.ToEContainer, Nothing)), LAP.IgnoreICopier)
End Function End Function
End Structure End Structure

View File

@@ -62,6 +62,7 @@ Namespace Editors
Dim TP_FEED_SES As System.Windows.Forms.TableLayoutPanel Dim TP_FEED_SES As System.Windows.Forms.TableLayoutPanel
Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TP_FEED_SPEC_SEARCH As System.Windows.Forms.TableLayoutPanel
Dim TAB_NOTIFY As System.Windows.Forms.TabPage Dim TAB_NOTIFY As System.Windows.Forms.TabPage
Dim TP_NOTIFY_MAIN As System.Windows.Forms.TableLayoutPanel Dim TP_NOTIFY_MAIN As System.Windows.Forms.TableLayoutPanel
Dim TP_ENVIR As System.Windows.Forms.TableLayoutPanel Dim TP_ENVIR As System.Windows.Forms.TableLayoutPanel
@@ -150,6 +151,8 @@ Namespace Editors
Me.CH_FEED_UP_FILE_LOC_MOVE = New System.Windows.Forms.CheckBox() Me.CH_FEED_UP_FILE_LOC_MOVE = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_ALL_F6_NOTIFY = New System.Windows.Forms.CheckBox() Me.CH_DOWN_ALL_F6_NOTIFY = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_ALL_NOTIFY = New System.Windows.Forms.CheckBox() Me.CH_DOWN_ALL_NOTIFY = New System.Windows.Forms.CheckBox()
Me.CH_FEED_SPEC_SEARCH = New System.Windows.Forms.CheckBox()
Me.CH_FEED_SPEC_SEARCH_DEEP = New System.Windows.Forms.CheckBox()
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox() Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox()
@@ -163,6 +166,8 @@ Namespace Editors
Me.CH_RECYCLE_DEL = New System.Windows.Forms.CheckBox() Me.CH_RECYCLE_DEL = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_OPEN_PROGRESS = New System.Windows.Forms.CheckBox() Me.CH_DOWN_OPEN_PROGRESS = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_ALL_F6_USE = New System.Windows.Forms.CheckBox() Me.CH_DOWN_ALL_F6_USE = New System.Windows.Forms.CheckBox()
Me.TXT_SCHEDULER_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL = New System.Windows.Forms.CheckBox()
Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_DOWN_COMPLETE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_DOWN_COMPLETE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_UNAME_UP = New System.Windows.Forms.CheckBox() Me.CH_UNAME_UP = New System.Windows.Forms.CheckBox()
@@ -180,6 +185,8 @@ Namespace Editors
Me.NUM_FEED_STORE_SESSION_DATA = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.NUM_FEED_STORE_SESSION_DATA = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.NUM_FEED_SES_CURR_LOAD_LAST = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.NUM_FEED_SES_CURR_LOAD_LAST = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_FEED_ADD_SITE = New System.Windows.Forms.CheckBox() Me.CH_FEED_ADD_SITE = New System.Windows.Forms.CheckBox()
Me.CH_FEED_ADD_TYPE = New System.Windows.Forms.CheckBox()
Me.CH_FEED_ESC_TO_CLOSE = New System.Windows.Forms.CheckBox()
Me.TXT_YTDLP = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_YTDLP = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_FFMPEG = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_FFMPEG = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_CURL = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CURL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
@@ -205,7 +212,7 @@ Namespace Editors
Me.TAB_MAIN = New System.Windows.Forms.TabControl() Me.TAB_MAIN = New System.Windows.Forms.TabControl()
Me.TAB_ENVIR = New System.Windows.Forms.TabPage() Me.TAB_ENVIR = New System.Windows.Forms.TabPage()
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
Me.CH_FEED_ADD_TYPE = New System.Windows.Forms.CheckBox() Me.CH_FEED_OPEN_CTRLF = New System.Windows.Forms.CheckBox()
TP_BASIS = New System.Windows.Forms.TableLayoutPanel() TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel() TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel() TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
@@ -230,6 +237,7 @@ Namespace Editors
TP_FEED = New System.Windows.Forms.TableLayoutPanel() TP_FEED = New System.Windows.Forms.TableLayoutPanel()
TP_FEED_IMG_COUNT = New System.Windows.Forms.TableLayoutPanel() TP_FEED_IMG_COUNT = New System.Windows.Forms.TableLayoutPanel()
TP_FEED_SES = New System.Windows.Forms.TableLayoutPanel() TP_FEED_SES = New System.Windows.Forms.TableLayoutPanel()
TP_FEED_SPEC_SEARCH = New System.Windows.Forms.TableLayoutPanel()
TAB_NOTIFY = New System.Windows.Forms.TabPage() TAB_NOTIFY = New System.Windows.Forms.TabPage()
TP_NOTIFY_MAIN = New System.Windows.Forms.TableLayoutPanel() TP_NOTIFY_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_ENVIR = New System.Windows.Forms.TableLayoutPanel() TP_ENVIR = New System.Windows.Forms.TableLayoutPanel()
@@ -267,6 +275,7 @@ Namespace Editors
TP_OPEN_INFO.SuspendLayout() TP_OPEN_INFO.SuspendLayout()
TP_OPEN_PROGRESS.SuspendLayout() TP_OPEN_PROGRESS.SuspendLayout()
TP_BEHAVIOR_F6.SuspendLayout() TP_BEHAVIOR_F6.SuspendLayout()
CType(Me.TXT_SCHEDULER_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit()
TAB_DOWN.SuspendLayout() TAB_DOWN.SuspendLayout()
TP_DOWNLOADING.SuspendLayout() TP_DOWNLOADING.SuspendLayout()
CType(Me.TXT_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit()
@@ -282,6 +291,7 @@ Namespace Editors
TP_FEED_SES.SuspendLayout() TP_FEED_SES.SuspendLayout()
CType(Me.NUM_FEED_STORE_SESSION_DATA, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.NUM_FEED_STORE_SESSION_DATA, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.NUM_FEED_SES_CURR_LOAD_LAST, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.NUM_FEED_SES_CURR_LOAD_LAST, System.ComponentModel.ISupportInitialize).BeginInit()
TP_FEED_SPEC_SEARCH.SuspendLayout()
TAB_NOTIFY.SuspendLayout() TAB_NOTIFY.SuspendLayout()
TP_NOTIFY_MAIN.SuspendLayout() TP_NOTIFY_MAIN.SuspendLayout()
TP_ENVIR.SuspendLayout() TP_ENVIR.SuspendLayout()
@@ -340,7 +350,7 @@ Namespace Editors
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BASIS.Size = New System.Drawing.Size(615, 393) TP_BASIS.Size = New System.Drawing.Size(615, 418)
TP_BASIS.TabIndex = 0 TP_BASIS.TabIndex = 0
' '
'TXT_GLOBAL_PATH 'TXT_GLOBAL_PATH
@@ -1096,6 +1106,31 @@ Namespace Editors
TT_MAIN.SetToolTip(Me.CH_DOWN_ALL_NOTIFY, "Request confirmation to download all users anyway") TT_MAIN.SetToolTip(Me.CH_DOWN_ALL_NOTIFY, "Request confirmation to download all users anyway")
Me.CH_DOWN_ALL_NOTIFY.UseVisualStyleBackColor = True Me.CH_DOWN_ALL_NOTIFY.UseVisualStyleBackColor = True
' '
'CH_FEED_SPEC_SEARCH
'
Me.CH_FEED_SPEC_SEARCH.AutoSize = True
Me.CH_FEED_SPEC_SEARCH.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_SPEC_SEARCH.Location = New System.Drawing.Point(3, 3)
Me.CH_FEED_SPEC_SEARCH.Name = "CH_FEED_SPEC_SEARCH"
Me.CH_FEED_SPEC_SEARCH.Size = New System.Drawing.Size(303, 19)
Me.CH_FEED_SPEC_SEARCH.TabIndex = 0
Me.CH_FEED_SPEC_SEARCH.Text = "Search missing files (special feeds)"
TT_MAIN.SetToolTip(Me.CH_FEED_SPEC_SEARCH, "Search for missing file in the entire user folder")
Me.CH_FEED_SPEC_SEARCH.UseVisualStyleBackColor = True
'
'CH_FEED_SPEC_SEARCH_DEEP
'
Me.CH_FEED_SPEC_SEARCH_DEEP.AutoSize = True
Me.CH_FEED_SPEC_SEARCH_DEEP.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_SPEC_SEARCH_DEEP.Location = New System.Drawing.Point(312, 3)
Me.CH_FEED_SPEC_SEARCH_DEEP.Name = "CH_FEED_SPEC_SEARCH_DEEP"
Me.CH_FEED_SPEC_SEARCH_DEEP.Size = New System.Drawing.Size(304, 19)
Me.CH_FEED_SPEC_SEARCH_DEEP.TabIndex = 1
Me.CH_FEED_SPEC_SEARCH_DEEP.Text = "Search missing files (special feeds): deep search"
TT_MAIN.SetToolTip(Me.CH_FEED_SPEC_SEARCH_DEEP, "Deep search means that the missing file will be searched in other users' location" &
"s as well.")
Me.CH_FEED_SPEC_SEARCH_DEEP.UseVisualStyleBackColor = True
'
'TP_CHANNELS_IMGS 'TP_CHANNELS_IMGS
' '
TP_CHANNELS_IMGS.ColumnCount = 2 TP_CHANNELS_IMGS.ColumnCount = 2
@@ -1147,7 +1182,7 @@ Namespace Editors
TAB_BASIS.Location = New System.Drawing.Point(4, 22) TAB_BASIS.Location = New System.Drawing.Point(4, 22)
TAB_BASIS.Name = "TAB_BASIS" TAB_BASIS.Name = "TAB_BASIS"
TAB_BASIS.Padding = New System.Windows.Forms.Padding(3) TAB_BASIS.Padding = New System.Windows.Forms.Padding(3)
TAB_BASIS.Size = New System.Drawing.Size(621, 399) TAB_BASIS.Size = New System.Drawing.Size(621, 424)
TAB_BASIS.TabIndex = 0 TAB_BASIS.TabIndex = 0
TAB_BASIS.Text = "Basis" TAB_BASIS.Text = "Basis"
' '
@@ -1157,7 +1192,7 @@ Namespace Editors
TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22) TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22)
TAB_DEFAULTS.Name = "TAB_DEFAULTS" TAB_DEFAULTS.Name = "TAB_DEFAULTS"
TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3) TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3)
TAB_DEFAULTS.Size = New System.Drawing.Size(621, 399) TAB_DEFAULTS.Size = New System.Drawing.Size(621, 424)
TAB_DEFAULTS.TabIndex = 1 TAB_DEFAULTS.TabIndex = 1
TAB_DEFAULTS.Text = "Defaults" TAB_DEFAULTS.Text = "Defaults"
' '
@@ -1183,7 +1218,7 @@ Namespace Editors
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DEFS.Size = New System.Drawing.Size(615, 393) TP_DEFS.Size = New System.Drawing.Size(615, 418)
TP_DEFS.TabIndex = 0 TP_DEFS.TabIndex = 0
' '
'CH_DOWN_IMAGES_NATIVE 'CH_DOWN_IMAGES_NATIVE
@@ -1203,7 +1238,7 @@ Namespace Editors
TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22) TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22)
TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS" TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS"
TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3) TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3)
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(621, 399) TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(621, 424)
TAB_DEFS_CHANNELS.TabIndex = 4 TAB_DEFS_CHANNELS.TabIndex = 4
TAB_DEFS_CHANNELS.Text = "Channels" TAB_DEFS_CHANNELS.Text = "Channels"
' '
@@ -1229,7 +1264,7 @@ Namespace Editors
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_CHANNELS.Size = New System.Drawing.Size(615, 393) TP_CHANNELS.Size = New System.Drawing.Size(615, 418)
TP_CHANNELS.TabIndex = 0 TP_CHANNELS.TabIndex = 0
' '
'TXT_CHANNEL_USER_POST_LIMIT 'TXT_CHANNEL_USER_POST_LIMIT
@@ -1268,7 +1303,7 @@ Namespace Editors
TAB_BEHAVIOR.Controls.Add(TP_BEHAVIOR) TAB_BEHAVIOR.Controls.Add(TP_BEHAVIOR)
TAB_BEHAVIOR.Location = New System.Drawing.Point(4, 22) TAB_BEHAVIOR.Location = New System.Drawing.Point(4, 22)
TAB_BEHAVIOR.Name = "TAB_BEHAVIOR" TAB_BEHAVIOR.Name = "TAB_BEHAVIOR"
TAB_BEHAVIOR.Size = New System.Drawing.Size(621, 399) TAB_BEHAVIOR.Size = New System.Drawing.Size(621, 424)
TAB_BEHAVIOR.TabIndex = 5 TAB_BEHAVIOR.TabIndex = 5
TAB_BEHAVIOR.Text = "Behavior" TAB_BEHAVIOR.Text = "Behavior"
' '
@@ -1286,10 +1321,13 @@ Namespace Editors
TP_BEHAVIOR.Controls.Add(Me.CH_RECYCLE_DEL, 0, 3) TP_BEHAVIOR.Controls.Add(Me.CH_RECYCLE_DEL, 0, 3)
TP_BEHAVIOR.Controls.Add(TP_OPEN_PROGRESS, 0, 5) TP_BEHAVIOR.Controls.Add(TP_OPEN_PROGRESS, 0, 5)
TP_BEHAVIOR.Controls.Add(TP_BEHAVIOR_F6, 0, 8) TP_BEHAVIOR.Controls.Add(TP_BEHAVIOR_F6, 0, 8)
TP_BEHAVIOR.Controls.Add(Me.TXT_SCHEDULER_SCRIPT, 0, 9)
TP_BEHAVIOR.Controls.Add(Me.CH_SCHEDULER_SCRIPT_EX_MANUAL, 0, 10)
TP_BEHAVIOR.Controls.Add(Me.CH_FEED_OPEN_CTRLF, 0, 11)
TP_BEHAVIOR.Dock = System.Windows.Forms.DockStyle.Fill TP_BEHAVIOR.Dock = System.Windows.Forms.DockStyle.Fill
TP_BEHAVIOR.Location = New System.Drawing.Point(0, 0) TP_BEHAVIOR.Location = New System.Drawing.Point(0, 0)
TP_BEHAVIOR.Name = "TP_BEHAVIOR" TP_BEHAVIOR.Name = "TP_BEHAVIOR"
TP_BEHAVIOR.RowCount = 10 TP_BEHAVIOR.RowCount = 13
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
@@ -1299,10 +1337,11 @@ Namespace Editors
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_BEHAVIOR.Size = New System.Drawing.Size(621, 424)
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BEHAVIOR.Size = New System.Drawing.Size(621, 399)
TP_BEHAVIOR.TabIndex = 0 TP_BEHAVIOR.TabIndex = 0
' '
'TXT_FOLDER_CMD 'TXT_FOLDER_CMD
@@ -1468,12 +1507,37 @@ Namespace Editors
Me.CH_DOWN_ALL_F6_USE.Text = "Use 'F6' to download all users" Me.CH_DOWN_ALL_F6_USE.Text = "Use 'F6' to download all users"
Me.CH_DOWN_ALL_F6_USE.UseVisualStyleBackColor = True Me.CH_DOWN_ALL_F6_USE.UseVisualStyleBackColor = True
' '
'TXT_SCHEDULER_SCRIPT
'
Me.TXT_SCHEDULER_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SCHEDULER_SCRIPT.CaptionText = "Scheduler script"
Me.TXT_SCHEDULER_SCRIPT.CaptionToolTipEnabled = True
Me.TXT_SCHEDULER_SCRIPT.CaptionToolTipText = "Execute the following script after the scheduler plan is completed"
Me.TXT_SCHEDULER_SCRIPT.CaptionWidth = 115.0R
Me.TXT_SCHEDULER_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SCHEDULER_SCRIPT.Location = New System.Drawing.Point(4, 244)
Me.TXT_SCHEDULER_SCRIPT.Name = "TXT_SCHEDULER_SCRIPT"
Me.TXT_SCHEDULER_SCRIPT.Size = New System.Drawing.Size(613, 22)
Me.TXT_SCHEDULER_SCRIPT.TabIndex = 9
'
'CH_SCHEDULER_SCRIPT_EX_MANUAL
'
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.AutoSize = True
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.Location = New System.Drawing.Point(4, 273)
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.Name = "CH_SCHEDULER_SCRIPT_EX_MANUAL"
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.Size = New System.Drawing.Size(613, 19)
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.TabIndex = 10
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.Text = "Disable execution of 'Scheduler script' after completion of 'Manual' scheduler pl" &
"ans"
Me.CH_SCHEDULER_SCRIPT_EX_MANUAL.UseVisualStyleBackColor = True
'
'TAB_DOWN 'TAB_DOWN
' '
TAB_DOWN.Controls.Add(TP_DOWNLOADING) TAB_DOWN.Controls.Add(TP_DOWNLOADING)
TAB_DOWN.Location = New System.Drawing.Point(4, 22) TAB_DOWN.Location = New System.Drawing.Point(4, 22)
TAB_DOWN.Name = "TAB_DOWN" TAB_DOWN.Name = "TAB_DOWN"
TAB_DOWN.Size = New System.Drawing.Size(621, 399) TAB_DOWN.Size = New System.Drawing.Size(621, 424)
TAB_DOWN.TabIndex = 6 TAB_DOWN.TabIndex = 6
TAB_DOWN.Text = "Downloading" TAB_DOWN.Text = "Downloading"
' '
@@ -1509,7 +1573,7 @@ Namespace Editors
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DOWNLOADING.Size = New System.Drawing.Size(621, 399) TP_DOWNLOADING.Size = New System.Drawing.Size(621, 424)
TP_DOWNLOADING.TabIndex = 1 TP_DOWNLOADING.TabIndex = 1
' '
'TXT_SCRIPT 'TXT_SCRIPT
@@ -1613,7 +1677,7 @@ Namespace Editors
TAB_FEED.Controls.Add(TP_FEED) TAB_FEED.Controls.Add(TP_FEED)
TAB_FEED.Location = New System.Drawing.Point(4, 22) TAB_FEED.Location = New System.Drawing.Point(4, 22)
TAB_FEED.Name = "TAB_FEED" TAB_FEED.Name = "TAB_FEED"
TAB_FEED.Size = New System.Drawing.Size(621, 374) TAB_FEED.Size = New System.Drawing.Size(621, 424)
TAB_FEED.TabIndex = 7 TAB_FEED.TabIndex = 7
TAB_FEED.Text = "Feed" TAB_FEED.Text = "Feed"
' '
@@ -1635,10 +1699,12 @@ Namespace Editors
TP_FEED.Controls.Add(TP_FEED_SES, 0, 8) TP_FEED.Controls.Add(TP_FEED_SES, 0, 8)
TP_FEED.Controls.Add(Me.CH_FEED_ADD_SITE, 0, 5) TP_FEED.Controls.Add(Me.CH_FEED_ADD_SITE, 0, 5)
TP_FEED.Controls.Add(Me.CH_FEED_ADD_TYPE, 0, 6) TP_FEED.Controls.Add(Me.CH_FEED_ADD_TYPE, 0, 6)
TP_FEED.Controls.Add(Me.CH_FEED_ESC_TO_CLOSE, 0, 13)
TP_FEED.Controls.Add(TP_FEED_SPEC_SEARCH, 0, 14)
TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill
TP_FEED.Location = New System.Drawing.Point(0, 0) TP_FEED.Location = New System.Drawing.Point(0, 0)
TP_FEED.Name = "TP_FEED" TP_FEED.Name = "TP_FEED"
TP_FEED.RowCount = 14 TP_FEED.RowCount = 16
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
@@ -1652,8 +1718,11 @@ Namespace Editors
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FEED.Size = New System.Drawing.Size(621, 374) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_FEED.Size = New System.Drawing.Size(621, 424)
TP_FEED.TabIndex = 0 TP_FEED.TabIndex = 0
' '
'TP_FEED_IMG_COUNT 'TP_FEED_IMG_COUNT
@@ -1867,12 +1936,51 @@ Namespace Editors
Me.CH_FEED_ADD_SITE.Text = "Add the site name to the post title" Me.CH_FEED_ADD_SITE.Text = "Add the site name to the post title"
Me.CH_FEED_ADD_SITE.UseVisualStyleBackColor = True Me.CH_FEED_ADD_SITE.UseVisualStyleBackColor = True
' '
'CH_FEED_ADD_TYPE
'
Me.CH_FEED_ADD_TYPE.AutoSize = True
Me.CH_FEED_ADD_TYPE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_ADD_TYPE.Location = New System.Drawing.Point(4, 166)
Me.CH_FEED_ADD_TYPE.Name = "CH_FEED_ADD_TYPE"
Me.CH_FEED_ADD_TYPE.Size = New System.Drawing.Size(613, 19)
Me.CH_FEED_ADD_TYPE.TabIndex = 6
Me.CH_FEED_ADD_TYPE.Text = "Add the file type to the post title"
Me.CH_FEED_ADD_TYPE.UseVisualStyleBackColor = True
'
'CH_FEED_ESC_TO_CLOSE
'
Me.CH_FEED_ESC_TO_CLOSE.AutoSize = True
Me.CH_FEED_ESC_TO_CLOSE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_ESC_TO_CLOSE.Location = New System.Drawing.Point(4, 351)
Me.CH_FEED_ESC_TO_CLOSE.Name = "CH_FEED_ESC_TO_CLOSE"
Me.CH_FEED_ESC_TO_CLOSE.Size = New System.Drawing.Size(613, 19)
Me.CH_FEED_ESC_TO_CLOSE.TabIndex = 13
Me.CH_FEED_ESC_TO_CLOSE.Text = "Use the 'Esc' key to close the form"
Me.CH_FEED_ESC_TO_CLOSE.UseVisualStyleBackColor = True
'
'TP_FEED_SPEC_SEARCH
'
TP_FEED_SPEC_SEARCH.ColumnCount = 2
TP_FEED_SPEC_SEARCH.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_FEED_SPEC_SEARCH.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_FEED_SPEC_SEARCH.Controls.Add(Me.CH_FEED_SPEC_SEARCH, 0, 0)
TP_FEED_SPEC_SEARCH.Controls.Add(Me.CH_FEED_SPEC_SEARCH_DEEP, 1, 0)
TP_FEED_SPEC_SEARCH.Dock = System.Windows.Forms.DockStyle.Fill
TP_FEED_SPEC_SEARCH.Location = New System.Drawing.Point(1, 374)
TP_FEED_SPEC_SEARCH.Margin = New System.Windows.Forms.Padding(0)
TP_FEED_SPEC_SEARCH.Name = "TP_FEED_SPEC_SEARCH"
TP_FEED_SPEC_SEARCH.RowCount = 1
TP_FEED_SPEC_SEARCH.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FEED_SPEC_SEARCH.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED_SPEC_SEARCH.Size = New System.Drawing.Size(619, 25)
TP_FEED_SPEC_SEARCH.TabIndex = 14
'
'TAB_NOTIFY 'TAB_NOTIFY
' '
TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN) TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN)
TAB_NOTIFY.Location = New System.Drawing.Point(4, 22) TAB_NOTIFY.Location = New System.Drawing.Point(4, 22)
TAB_NOTIFY.Name = "TAB_NOTIFY" TAB_NOTIFY.Name = "TAB_NOTIFY"
TAB_NOTIFY.Size = New System.Drawing.Size(621, 399) TAB_NOTIFY.Size = New System.Drawing.Size(621, 424)
TAB_NOTIFY.TabIndex = 8 TAB_NOTIFY.TabIndex = 8
TAB_NOTIFY.Text = "Notifications" TAB_NOTIFY.Text = "Notifications"
' '
@@ -1904,7 +2012,7 @@ Namespace Editors
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_NOTIFY_MAIN.Size = New System.Drawing.Size(621, 399) TP_NOTIFY_MAIN.Size = New System.Drawing.Size(621, 424)
TP_NOTIFY_MAIN.TabIndex = 0 TP_NOTIFY_MAIN.TabIndex = 0
' '
'TP_ENVIR 'TP_ENVIR
@@ -1927,7 +2035,7 @@ Namespace Editors
TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_ENVIR.Size = New System.Drawing.Size(621, 399) TP_ENVIR.Size = New System.Drawing.Size(621, 424)
TP_ENVIR.TabIndex = 0 TP_ENVIR.TabIndex = 0
' '
'TXT_YTDLP 'TXT_YTDLP
@@ -2058,7 +2166,7 @@ Namespace Editors
TAB_STD.Controls.Add(TP_STD) TAB_STD.Controls.Add(TP_STD)
TAB_STD.Location = New System.Drawing.Point(4, 22) TAB_STD.Location = New System.Drawing.Point(4, 22)
TAB_STD.Name = "TAB_STD" TAB_STD.Name = "TAB_STD"
TAB_STD.Size = New System.Drawing.Size(621, 399) TAB_STD.Size = New System.Drawing.Size(621, 424)
TAB_STD.TabIndex = 10 TAB_STD.TabIndex = 10
TAB_STD.Text = "Downloader" TAB_STD.Text = "Downloader"
' '
@@ -2100,7 +2208,7 @@ Namespace Editors
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_STD.Size = New System.Drawing.Size(621, 399) TP_STD.Size = New System.Drawing.Size(621, 424)
TP_STD.TabIndex = 0 TP_STD.TabIndex = 0
' '
'TXT_STD_MAX_JOBS_COUNT 'TXT_STD_MAX_JOBS_COUNT
@@ -2199,7 +2307,7 @@ Namespace Editors
TAB_DESIGN.Controls.Add(TP_DESIGN) TAB_DESIGN.Controls.Add(TP_DESIGN)
TAB_DESIGN.Location = New System.Drawing.Point(4, 22) TAB_DESIGN.Location = New System.Drawing.Point(4, 22)
TAB_DESIGN.Name = "TAB_DESIGN" TAB_DESIGN.Name = "TAB_DESIGN"
TAB_DESIGN.Size = New System.Drawing.Size(621, 399) TAB_DESIGN.Size = New System.Drawing.Size(621, 424)
TAB_DESIGN.TabIndex = 11 TAB_DESIGN.TabIndex = 11
TAB_DESIGN.Text = "Design" TAB_DESIGN.Text = "Design"
' '
@@ -2225,7 +2333,7 @@ Namespace Editors
TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DESIGN.Size = New System.Drawing.Size(621, 399) TP_DESIGN.Size = New System.Drawing.Size(621, 424)
TP_DESIGN.TabIndex = 0 TP_DESIGN.TabIndex = 0
' '
'TXT_PRG_TITLE 'TXT_PRG_TITLE
@@ -2336,7 +2444,7 @@ Namespace Editors
TP_HEADERS_DEF.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_HEADERS_DEF.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_HEADERS_DEF.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_HEADERS_DEF.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_HEADERS_DEF.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_HEADERS_DEF.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_HEADERS_DEF.Size = New System.Drawing.Size(621, 399) TP_HEADERS_DEF.Size = New System.Drawing.Size(621, 424)
TP_HEADERS_DEF.TabIndex = 0 TP_HEADERS_DEF.TabIndex = 0
' '
'TXT_H_DEF_UserAgent 'TXT_H_DEF_UserAgent
@@ -2414,7 +2522,7 @@ Namespace Editors
TAB_HEADERS.Controls.Add(TP_HEADERS_DEF) TAB_HEADERS.Controls.Add(TP_HEADERS_DEF)
TAB_HEADERS.Location = New System.Drawing.Point(4, 22) TAB_HEADERS.Location = New System.Drawing.Point(4, 22)
TAB_HEADERS.Name = "TAB_HEADERS" TAB_HEADERS.Name = "TAB_HEADERS"
TAB_HEADERS.Size = New System.Drawing.Size(621, 399) TAB_HEADERS.Size = New System.Drawing.Size(621, 424)
TAB_HEADERS.TabIndex = 12 TAB_HEADERS.TabIndex = 12
TAB_HEADERS.Text = "Headers" TAB_HEADERS.Text = "Headers"
' '
@@ -2435,7 +2543,7 @@ Namespace Editors
Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0) Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0)
Me.TAB_MAIN.Name = "TAB_MAIN" Me.TAB_MAIN.Name = "TAB_MAIN"
Me.TAB_MAIN.SelectedIndex = 0 Me.TAB_MAIN.SelectedIndex = 0
Me.TAB_MAIN.Size = New System.Drawing.Size(629, 400) Me.TAB_MAIN.Size = New System.Drawing.Size(629, 450)
Me.TAB_MAIN.TabIndex = 1 Me.TAB_MAIN.TabIndex = 1
' '
'TAB_ENVIR 'TAB_ENVIR
@@ -2443,7 +2551,7 @@ Namespace Editors
Me.TAB_ENVIR.Controls.Add(TP_ENVIR) Me.TAB_ENVIR.Controls.Add(TP_ENVIR)
Me.TAB_ENVIR.Location = New System.Drawing.Point(4, 22) Me.TAB_ENVIR.Location = New System.Drawing.Point(4, 22)
Me.TAB_ENVIR.Name = "TAB_ENVIR" Me.TAB_ENVIR.Name = "TAB_ENVIR"
Me.TAB_ENVIR.Size = New System.Drawing.Size(621, 399) Me.TAB_ENVIR.Size = New System.Drawing.Size(621, 424)
Me.TAB_ENVIR.TabIndex = 9 Me.TAB_ENVIR.TabIndex = 9
Me.TAB_ENVIR.Text = "Environment" Me.TAB_ENVIR.Text = "Environment"
' '
@@ -2453,40 +2561,42 @@ Namespace Editors
'CONTAINER_MAIN.ContentPanel 'CONTAINER_MAIN.ContentPanel
' '
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN) Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(629, 400) Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(629, 450)
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN" Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN"
Me.CONTAINER_MAIN.RightToolStripPanelVisible = False Me.CONTAINER_MAIN.RightToolStripPanelVisible = False
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(629, 425) Me.CONTAINER_MAIN.Size = New System.Drawing.Size(629, 450)
Me.CONTAINER_MAIN.TabIndex = 0 Me.CONTAINER_MAIN.TabIndex = 0
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
' '
'CH_FEED_ADD_TYPE 'CH_FEED_OPEN_CTRLF
' '
Me.CH_FEED_ADD_TYPE.AutoSize = True Me.CH_FEED_OPEN_CTRLF.AutoSize = True
Me.CH_FEED_ADD_TYPE.Dock = System.Windows.Forms.DockStyle.Fill Me.CH_FEED_OPEN_CTRLF.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_ADD_TYPE.Location = New System.Drawing.Point(4, 166) Me.CH_FEED_OPEN_CTRLF.Location = New System.Drawing.Point(4, 299)
Me.CH_FEED_ADD_TYPE.Name = "CH_FEED_ADD_TYPE" Me.CH_FEED_OPEN_CTRLF.Name = "CH_FEED_OPEN_CTRLF"
Me.CH_FEED_ADD_TYPE.Size = New System.Drawing.Size(613, 19) Me.CH_FEED_OPEN_CTRLF.Size = New System.Drawing.Size(613, 19)
Me.CH_FEED_ADD_TYPE.TabIndex = 6 Me.CH_FEED_OPEN_CTRLF.TabIndex = 11
Me.CH_FEED_ADD_TYPE.Text = "Add the file type to the post title" Me.CH_FEED_OPEN_CTRLF.Text = "Use 'Ctrl+F' to open the Feed"
Me.CH_FEED_ADD_TYPE.UseVisualStyleBackColor = True TT_MAIN.SetToolTip(Me.CH_FEED_OPEN_CTRLF, "If checked, 'Ctrl+F' will be used to open the Feed. Otherwise, 'Alt+F' will be us" &
"ed.")
Me.CH_FEED_OPEN_CTRLF.UseVisualStyleBackColor = True
' '
'GlobalSettingsForm 'GlobalSettingsForm
' '
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(629, 425) Me.ClientSize = New System.Drawing.Size(629, 450)
Me.Controls.Add(Me.CONTAINER_MAIN) Me.Controls.Add(Me.CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.Resources.SettingsIcon_48 Me.Icon = Global.SCrawler.My.Resources.Resources.SettingsIcon_48
Me.KeyPreview = True Me.KeyPreview = True
Me.MaximizeBox = False Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(645, 464) Me.MaximumSize = New System.Drawing.Size(645, 489)
Me.MinimizeBox = False Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(645, 464) Me.MinimumSize = New System.Drawing.Size(645, 489)
Me.Name = "GlobalSettingsForm" Me.Name = "GlobalSettingsForm"
Me.ShowInTaskbar = False Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
@@ -2528,6 +2638,7 @@ Namespace Editors
TP_OPEN_PROGRESS.PerformLayout() TP_OPEN_PROGRESS.PerformLayout()
TP_BEHAVIOR_F6.ResumeLayout(False) TP_BEHAVIOR_F6.ResumeLayout(False)
TP_BEHAVIOR_F6.PerformLayout() TP_BEHAVIOR_F6.PerformLayout()
CType(Me.TXT_SCHEDULER_SCRIPT, System.ComponentModel.ISupportInitialize).EndInit()
TAB_DOWN.ResumeLayout(False) TAB_DOWN.ResumeLayout(False)
TP_DOWNLOADING.ResumeLayout(False) TP_DOWNLOADING.ResumeLayout(False)
TP_DOWNLOADING.PerformLayout() TP_DOWNLOADING.PerformLayout()
@@ -2546,6 +2657,8 @@ Namespace Editors
TP_FEED_SES.ResumeLayout(False) TP_FEED_SES.ResumeLayout(False)
CType(Me.NUM_FEED_STORE_SESSION_DATA, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.NUM_FEED_STORE_SESSION_DATA, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.NUM_FEED_SES_CURR_LOAD_LAST, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.NUM_FEED_SES_CURR_LOAD_LAST, System.ComponentModel.ISupportInitialize).EndInit()
TP_FEED_SPEC_SEARCH.ResumeLayout(False)
TP_FEED_SPEC_SEARCH.PerformLayout()
TAB_NOTIFY.ResumeLayout(False) TAB_NOTIFY.ResumeLayout(False)
TP_NOTIFY_MAIN.ResumeLayout(False) TP_NOTIFY_MAIN.ResumeLayout(False)
TP_NOTIFY_MAIN.PerformLayout() TP_NOTIFY_MAIN.PerformLayout()
@@ -2689,5 +2802,11 @@ Namespace Editors
Private WithEvents TXT_AUTO_BRUSH_MIN As PersonalUtilities.Forms.Controls.TextBoxExtended Private WithEvents TXT_AUTO_BRUSH_MIN As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_FEED_ADD_SITE As CheckBox Private WithEvents CH_FEED_ADD_SITE As CheckBox
Private WithEvents CH_FEED_ADD_TYPE As CheckBox Private WithEvents CH_FEED_ADD_TYPE As CheckBox
Private WithEvents CH_FEED_ESC_TO_CLOSE As CheckBox
Private WithEvents TXT_SCHEDULER_SCRIPT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_SCHEDULER_SCRIPT_EX_MANUAL As CheckBox
Private WithEvents CH_FEED_SPEC_SEARCH As CheckBox
Private WithEvents CH_FEED_SPEC_SEARCH_DEEP As CheckBox
Private WithEvents CH_FEED_OPEN_CTRLF As CheckBox
End Class End Class
End Namespace End Namespace

View File

@@ -364,6 +364,9 @@ You can find more detailed information about the missing posts in the form that
0 - only the session of the current day. 0 - only the session of the current day.
&gt;0 - the value (in minutes) that must elapse since last file download in a session for that session to be considered current.</value> &gt;0 - the value (in minutes) that must elapse since last file download in a session for that session to be considered current.</value>
</data> </data>
<metadata name="TP_FEED_SPEC_SEARCH.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TAB_NOTIFY.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="TAB_NOTIFY.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>

View File

@@ -77,6 +77,10 @@ Namespace Editors
CH_DOWN_ALL_F6_USE.Checked = .DownloadAll_UseF6 CH_DOWN_ALL_F6_USE.Checked = .DownloadAll_UseF6
CH_DOWN_ALL_F6_NOTIFY.Checked = .DownloadAll_UseF6_Confirm CH_DOWN_ALL_F6_NOTIFY.Checked = .DownloadAll_UseF6_Confirm
CH_DOWN_ALL_NOTIFY.Checked = .DownloadAll_Confirm CH_DOWN_ALL_NOTIFY.Checked = .DownloadAll_Confirm
TXT_SCHEDULER_SCRIPT.Text = .AutomationScript
TXT_SCHEDULER_SCRIPT.Checked = .AutomationScript.Use
CH_SCHEDULER_SCRIPT_EX_MANUAL.Checked = .AutomationScript_ExcludeManual
CH_FEED_OPEN_CTRLF.Checked = .FeedOpenCtrlF
'Notifications 'Notifications
CH_NOTIFY_SILENT.Checked = .NotificationsSilentMode CH_NOTIFY_SILENT.Checked = .NotificationsSilentMode
CH_NOTIFY_SHOW_BASE.Checked = .ShowNotifications CH_NOTIFY_SHOW_BASE.Checked = .ShowNotifications
@@ -161,6 +165,9 @@ Namespace Editors
CH_FEED_SHOW_FRIENDLY.Checked = .FeedShowFriendlyNames CH_FEED_SHOW_FRIENDLY.Checked = .FeedShowFriendlyNames
CH_FEED_SHOW_SPEC_MEDIAITEM.Checked = .FeedShowSpecialFeedsMediaItem CH_FEED_SHOW_SPEC_MEDIAITEM.Checked = .FeedShowSpecialFeedsMediaItem
CH_FEED_UP_FILE_LOC_MOVE.Checked = .FeedMoveCopyUpdateFileLocationOnMove CH_FEED_UP_FILE_LOC_MOVE.Checked = .FeedMoveCopyUpdateFileLocationOnMove
CH_FEED_ESC_TO_CLOSE.Checked = .FeedEscToClose
CH_FEED_SPEC_SEARCH.Checked = .FeedSpecialSearchForMissing
CH_FEED_SPEC_SEARCH_DEEP.Checked = .FeedSpecialSearchForMissing_Deep
End With End With
.MyFieldsChecker = New FieldsChecker .MyFieldsChecker = New FieldsChecker
With .MyFieldsCheckerE With .MyFieldsCheckerE
@@ -291,6 +298,10 @@ Namespace Editors
.DownloadAll_UseF6.Value = CH_DOWN_ALL_F6_USE.Checked .DownloadAll_UseF6.Value = CH_DOWN_ALL_F6_USE.Checked
.DownloadAll_UseF6_Confirm.Value = CH_DOWN_ALL_F6_NOTIFY.Checked .DownloadAll_UseF6_Confirm.Value = CH_DOWN_ALL_F6_NOTIFY.Checked
.DownloadAll_Confirm.Value = CH_DOWN_ALL_NOTIFY.Checked .DownloadAll_Confirm.Value = CH_DOWN_ALL_NOTIFY.Checked
.AutomationScript.Value = TXT_SCHEDULER_SCRIPT.Text
.AutomationScript.Use = TXT_SCHEDULER_SCRIPT.Checked
.AutomationScript_ExcludeManual.Value = CH_SCHEDULER_SCRIPT_EX_MANUAL.Checked
.FeedOpenCtrlF.Value = CH_FEED_OPEN_CTRLF.Checked
'Notifications 'Notifications
.NotificationsSilentMode = CH_NOTIFY_SILENT.Checked .NotificationsSilentMode = CH_NOTIFY_SILENT.Checked
.ShowNotifications.Value = CH_NOTIFY_SHOW_BASE.Checked .ShowNotifications.Value = CH_NOTIFY_SHOW_BASE.Checked
@@ -373,6 +384,9 @@ Namespace Editors
.FeedShowFriendlyNames.Value = CH_FEED_SHOW_FRIENDLY.Checked .FeedShowFriendlyNames.Value = CH_FEED_SHOW_FRIENDLY.Checked
.FeedShowSpecialFeedsMediaItem.Value = CH_FEED_SHOW_SPEC_MEDIAITEM.Checked .FeedShowSpecialFeedsMediaItem.Value = CH_FEED_SHOW_SPEC_MEDIAITEM.Checked
.FeedMoveCopyUpdateFileLocationOnMove.Value = CH_FEED_UP_FILE_LOC_MOVE.Checked .FeedMoveCopyUpdateFileLocationOnMove.Value = CH_FEED_UP_FILE_LOC_MOVE.Checked
.FeedEscToClose.Value = CH_FEED_ESC_TO_CLOSE.Checked
.FeedSpecialSearchForMissing.Value = CH_FEED_SPEC_SEARCH.Checked
.FeedSpecialSearchForMissing_Deep.Value = CH_FEED_SPEC_SEARCH_DEEP.Checked
FeedParametersChanged = { .FeedDataRows, .FeedDataColumns, .FeedEndless, .FeedBackColor, FeedParametersChanged = { .FeedDataRows, .FeedDataColumns, .FeedEndless, .FeedBackColor,
.FeedForeColor, .FeedCenterImage}.Cast(Of IXMLValue).Any(detector) .FeedForeColor, .FeedCenterImage}.Cast(Of IXMLValue).Any(detector)

View File

@@ -103,7 +103,7 @@ Namespace Editors
#End Region #End Region
#Region "Exchange, Path, Labels" #Region "Exchange, Path, Labels"
Friend Property MyExchangeOptions As Object = Nothing Friend Property MyExchangeOptions As Object = Nothing
Private ReadOnly _SpecPathPattern As RParams = RParams.DM("\w:\\.*", 0, EDP.ReturnValue) Private ReadOnly _SpecPathPattern As RParams = RParams.DM("(\w:\\|\\\\).*", 0, EDP.ReturnValue)
Private ReadOnly Property SpecialPath(ByVal s As SettingsHost) As SFile Private ReadOnly Property SpecialPath(ByVal s As SettingsHost) As SFile
Get Get
If TXT_SPEC_FOLDER.IsEmptyString Then If TXT_SPEC_FOLDER.IsEmptyString Then

View File

@@ -22,22 +22,10 @@ Friend Class LabelsKeeper : Implements ICollection(Of String), IMyEnumerator(Of
Return NewLabels.Count > 0 Return NewLabels.Count > 0
End Get End Get
End Property End Property
'URGENT: remove these properties (2024.03) Friend Sub New()
<Obsolete> Friend ReadOnly Property Current As XMLValuesCollection(Of String)
<Obsolete> Friend ReadOnly Property Excluded As XMLValuesCollection(Of String)
<Obsolete> Friend ReadOnly Property ExcludedIgnore As XMLValue(Of Boolean)
Friend Sub New(ByRef x As XmlFile)
LabelsList = New List(Of String) LabelsList = New List(Of String)
NewLabels = New List(Of String) NewLabels = New List(Of String)
If LabelsFile.Exists Then LabelsList.ListAddList(IO.File.ReadAllLines(LabelsFile), LAP.NotContainsOnly) If LabelsFile.Exists Then LabelsList.ListAddList(IO.File.ReadAllLines(LabelsFile), LAP.NotContainsOnly)
#Disable Warning BC40008
Current = New XMLValuesCollection(Of String)(IXMLValuesCollection.Modes.String, "LatestSelectedLabels",, x) With {.ListAddParameters = LAP.NotContainsOnly}
Excluded = New XMLValuesCollection(Of String)(IXMLValuesCollection.Modes.String, "LatestExcludedLabels",, x) With {.ListAddParameters = LAP.NotContainsOnly}
ExcludedIgnore = New XMLValue(Of Boolean)("LatestExcludedLabelsIgnore", False, x)
Dim lp As New ListAddParams(LAP.NotContainsOnly + LAP.IgnoreICopier)
If Current.Count > 0 Then LabelsList.ListAddList(Current, lp)
If Excluded.Count > 0 Then LabelsList.ListAddList(Excluded, lp)
#Enable Warning
End Sub End Sub
Friend ReadOnly Property ToList As List(Of String) Friend ReadOnly Property ToList As List(Of String)
Get Get
@@ -112,9 +100,7 @@ Friend Class LabelsKeeper : Implements ICollection(Of String), IMyEnumerator(Of
Private disposedValue As Boolean = False Private disposedValue As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue Then If Not disposedValue Then
#Disable Warning BC40008 If disposing Then Clear()
If disposing Then Clear() : Current.Dispose() : Excluded.Dispose()
#Enable Warning
disposedValue = True disposedValue = True
End If End If
End Sub End Sub

View File

@@ -40,12 +40,14 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Dim MENU_DOWN_ALL_SEP_3 As System.Windows.Forms.ToolStripSeparator Dim MENU_DOWN_ALL_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_4 As System.Windows.Forms.ToolStripSeparator Dim MENU_DOWN_ALL_SEP_4 As System.Windows.Forms.ToolStripSeparator
Dim MENU_INFO As System.Windows.Forms.ToolStripDropDownButton Dim MENU_INFO As System.Windows.Forms.ToolStripDropDownButton
Dim MENU_INFO_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MainFrame)) Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MainFrame))
Me.MENU_INFO_SHOW_INFO = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_INFO = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_SHOW_QUEUE = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_QUEUE = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_SHOW_MISSING = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_MISSING = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_SHOW_USER_METRICS = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_USER_METRICS = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_USER_SEARCH = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_SETTINGS = New System.Windows.Forms.ToolStripDropDownButton() Me.MENU_SETTINGS = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_SETTINGS = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_SETTINGS = New System.Windows.Forms.ToolStripMenuItem()
Me.Toolbar_TOP = New System.Windows.Forms.ToolStrip() Me.Toolbar_TOP = New System.Windows.Forms.ToolStrip()
@@ -140,6 +142,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
MENU_DOWN_ALL_SEP_3 = New System.Windows.Forms.ToolStripSeparator() MENU_DOWN_ALL_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_4 = New System.Windows.Forms.ToolStripSeparator() MENU_DOWN_ALL_SEP_4 = New System.Windows.Forms.ToolStripSeparator()
MENU_INFO = New System.Windows.Forms.ToolStripDropDownButton() MENU_INFO = New System.Windows.Forms.ToolStripDropDownButton()
MENU_INFO_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator() MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
Me.Toolbar_TOP.SuspendLayout() Me.Toolbar_TOP.SuspendLayout()
Me.Toolbar_BOTTOM.SuspendLayout() Me.Toolbar_BOTTOM.SuspendLayout()
@@ -235,7 +238,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'MENU_INFO 'MENU_INFO
' '
MENU_INFO.AutoToolTip = False MENU_INFO.AutoToolTip = False
MENU_INFO.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_INFO_SHOW_INFO, Me.MENU_INFO_SHOW_QUEUE, Me.MENU_INFO_SHOW_MISSING, Me.MENU_INFO_SHOW_USER_METRICS}) MENU_INFO.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_INFO_SHOW_INFO, Me.MENU_INFO_SHOW_QUEUE, Me.MENU_INFO_SHOW_MISSING, MENU_INFO_SEP_1, Me.MENU_INFO_SHOW_USER_METRICS, Me.MENU_INFO_USER_SEARCH})
MENU_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32 MENU_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
MENU_INFO.ImageTransparentColor = System.Drawing.Color.Magenta MENU_INFO.ImageTransparentColor = System.Drawing.Color.Magenta
MENU_INFO.Name = "MENU_INFO" MENU_INFO.Name = "MENU_INFO"
@@ -268,6 +271,11 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.MENU_INFO_SHOW_MISSING.Text = "Missing posts" Me.MENU_INFO_SHOW_MISSING.Text = "Missing posts"
Me.MENU_INFO_SHOW_MISSING.ToolTipText = "Open the 'Missing' form (show information about missing posts)." Me.MENU_INFO_SHOW_MISSING.ToolTipText = "Open the 'Missing' form (show information about missing posts)."
' '
'MENU_INFO_SEP_1
'
MENU_INFO_SEP_1.Name = "MENU_INFO_SEP_1"
MENU_INFO_SEP_1.Size = New System.Drawing.Size(209, 6)
'
'MENU_INFO_SHOW_USER_METRICS 'MENU_INFO_SHOW_USER_METRICS
' '
Me.MENU_INFO_SHOW_USER_METRICS.AutoToolTip = True Me.MENU_INFO_SHOW_USER_METRICS.AutoToolTip = True
@@ -277,6 +285,13 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.MENU_INFO_SHOW_USER_METRICS.Text = "User metrics" Me.MENU_INFO_SHOW_USER_METRICS.Text = "User metrics"
Me.MENU_INFO_SHOW_USER_METRICS.ToolTipText = "Open the ""User metrics' form (show information about the user's metrics (such as " & Me.MENU_INFO_SHOW_USER_METRICS.ToolTipText = "Open the ""User metrics' form (show information about the user's metrics (such as " &
"size, number of files, etc.))." "size, number of files, etc.))."
'
'MENU_INFO_USER_SEARCH
'
Me.MENU_INFO_USER_SEARCH.Image = Global.SCrawler.My.Resources.Resources.FindPic_16
Me.MENU_INFO_USER_SEARCH.Name = "MENU_INFO_USER_SEARCH"
Me.MENU_INFO_USER_SEARCH.Size = New System.Drawing.Size(212, 22)
Me.MENU_INFO_USER_SEARCH.Text = "Find user"
' '
'MENU_VIEW_SEP_1 'MENU_VIEW_SEP_1
' '
@@ -353,7 +368,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_FEED.Name = "BTT_FEED" Me.BTT_FEED.Name = "BTT_FEED"
Me.BTT_FEED.Size = New System.Drawing.Size(52, 22) Me.BTT_FEED.Size = New System.Drawing.Size(52, 22)
Me.BTT_FEED.Text = "Feed" Me.BTT_FEED.Text = "Feed"
Me.BTT_FEED.ToolTipText = "Feed of recently downloaded data" Me.BTT_FEED.ToolTipText = "Feed of recently downloaded data (Ctrl+F)"
' '
'BTT_CHANNELS 'BTT_CHANNELS
' '
@@ -664,7 +679,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_CONTEXT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16 Me.BTT_CONTEXT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_CONTEXT_DOWN.Name = "BTT_CONTEXT_DOWN" Me.BTT_CONTEXT_DOWN.Name = "BTT_CONTEXT_DOWN"
Me.BTT_CONTEXT_DOWN.Size = New System.Drawing.Size(221, 22) Me.BTT_CONTEXT_DOWN.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_DOWN.Text = "Download data" Me.BTT_CONTEXT_DOWN.Text = "Download"
Me.BTT_CONTEXT_DOWN.ToolTipText = "" Me.BTT_CONTEXT_DOWN.ToolTipText = ""
' '
'BTT_CONTEXT_DOWN_LIMITED 'BTT_CONTEXT_DOWN_LIMITED
@@ -673,7 +688,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_CONTEXT_DOWN_LIMITED.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16 Me.BTT_CONTEXT_DOWN_LIMITED.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_CONTEXT_DOWN_LIMITED.Name = "BTT_CONTEXT_DOWN_LIMITED" Me.BTT_CONTEXT_DOWN_LIMITED.Name = "BTT_CONTEXT_DOWN_LIMITED"
Me.BTT_CONTEXT_DOWN_LIMITED.Size = New System.Drawing.Size(221, 22) Me.BTT_CONTEXT_DOWN_LIMITED.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_DOWN_LIMITED.Text = "Download data limited" Me.BTT_CONTEXT_DOWN_LIMITED.Text = "Download (limited)"
Me.BTT_CONTEXT_DOWN_LIMITED.ToolTipText = "Download top ... posts" Me.BTT_CONTEXT_DOWN_LIMITED.ToolTipText = "Download top ... posts"
' '
'BTT_CONTEXT_DOWN_DATE_LIMIT 'BTT_CONTEXT_DOWN_DATE_LIMIT
@@ -681,7 +696,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16 Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Name = "BTT_CONTEXT_DOWN_DATE_LIMIT" Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Name = "BTT_CONTEXT_DOWN_DATE_LIMIT"
Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Size = New System.Drawing.Size(221, 22) Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Text = "Download data to the date" Me.BTT_CONTEXT_DOWN_DATE_LIMIT.Text = "Download (to the date)"
Me.BTT_CONTEXT_DOWN_DATE_LIMIT.ToolTipText = "" Me.BTT_CONTEXT_DOWN_DATE_LIMIT.ToolTipText = ""
' '
'BTT_CONTEXT_EDIT 'BTT_CONTEXT_EDIT
@@ -993,4 +1008,5 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Private WithEvents BTT_VIEW_FILTER_SAVE As ToolStripMenuItem Private WithEvents BTT_VIEW_FILTER_SAVE As ToolStripMenuItem
Private WithEvents BTT_VIEW_FILTER_LOAD As ToolStripMenuItem Private WithEvents BTT_VIEW_FILTER_LOAD As ToolStripMenuItem
Private WithEvents BTT_VIEW_FILTER_SAVE_AS_GROUP As ToolStripMenuItem Private WithEvents BTT_VIEW_FILTER_SAVE_AS_GROUP As ToolStripMenuItem
Private WithEvents MENU_INFO_USER_SEARCH As ToolStripMenuItem
End Class End Class

View File

@@ -171,6 +171,9 @@
<metadata name="MENU_INFO.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="MENU_INFO.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="MENU_INFO_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="MENU_VIEW_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>

View File

@@ -241,12 +241,14 @@ CloseResume:
If Not b Then If Not b Then
b = True b = True
If e.Control And e.KeyCode = Keys.F Then If Settings.ShortcutOpenFeed = e Then
MySearch.FormShow() BTT_FEED.PerformClick()
ElseIf e.Alt And e.KeyCode = Keys.A Then ElseIf e.Alt And e.KeyCode = Keys.A Then
BTT_DOWN_AUTOMATION.PerformClick() BTT_DOWN_AUTOMATION.PerformClick()
ElseIf e.Alt And e.KeyCode = Keys.P Then ElseIf e.Alt And e.KeyCode = Keys.P Then
BTT_PR_INFO.PerformClick() BTT_PR_INFO.PerformClick()
ElseIf Settings.ShortcutOpenSearch = e Or (e.Alt And e.KeyCode = Keys.U) Or (e.Control And e.KeyCode = Keys.U) Then
MySearch.FormShow()
Else Else
b = False b = False
End If End If
@@ -477,6 +479,9 @@ CloseResume:
Private Sub MENU_INFO_SHOW_USER_METRICS_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_USER_METRICS.Click Private Sub MENU_INFO_SHOW_USER_METRICS_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_USER_METRICS.Click
MyUserMetrics.FormShow(EDP.LogMessageValue) MyUserMetrics.FormShow(EDP.LogMessageValue)
End Sub End Sub
Private Sub MENU_INFO_USER_SEARCH_Click(sender As Object, e As EventArgs) Handles MENU_INFO_USER_SEARCH.Click
MySearch.FormShow()
End Sub
#End Region #End Region
Friend Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click Friend Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click
If MyFeed Is Nothing Then If MyFeed Is Nothing Then
@@ -1515,6 +1520,8 @@ CloseResume:
If Not user Is Nothing AndAlso user.IsCollection Then If Not user Is Nothing AndAlso user.IsCollection Then
With DirectCast(user, UserDataBind) With DirectCast(user, UserDataBind)
BTT_CONTEXT_DOWN.DropDownItems.AddRange(.ContextDown) BTT_CONTEXT_DOWN.DropDownItems.AddRange(.ContextDown)
BTT_CONTEXT_DOWN_LIMITED.DropDownItems.AddRange(.ContextDownLimit)
BTT_CONTEXT_DOWN_DATE_LIMIT.DropDownItems.AddRange(.ContextDownDate)
BTT_CONTEXT_EDIT.DropDownItems.AddRange(.ContextEdit) BTT_CONTEXT_EDIT.DropDownItems.AddRange(.ContextEdit)
BTT_CONTEXT_DELETE.DropDownItems.AddRange(.ContextDelete) BTT_CONTEXT_DELETE.DropDownItems.AddRange(.ContextDelete)
BTT_CONTEXT_ERASE.DropDownItems.AddRange(.ContextErase) BTT_CONTEXT_ERASE.DropDownItems.AddRange(.ContextErase)
@@ -1524,6 +1531,8 @@ CloseResume:
End If End If
Else Else
BTT_CONTEXT_DOWN.DropDownItems.Clear() BTT_CONTEXT_DOWN.DropDownItems.Clear()
BTT_CONTEXT_DOWN_LIMITED.DropDownItems.Clear()
BTT_CONTEXT_DOWN_DATE_LIMIT.DropDownItems.Clear()
BTT_CONTEXT_EDIT.DropDownItems.Clear() BTT_CONTEXT_EDIT.DropDownItems.Clear()
BTT_CONTEXT_DELETE.DropDownItems.Clear() BTT_CONTEXT_DELETE.DropDownItems.Clear()
BTT_CONTEXT_ERASE.DropDownItems.Clear() BTT_CONTEXT_ERASE.DropDownItems.Clear()
@@ -1629,10 +1638,11 @@ CloseResume:
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[MainFrame.GetSelectedUserArray]", New List(Of IUserData)) Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[MainFrame.GetSelectedUserArray]", New List(Of IUserData))
End Try End Try
End Function End Function
Private Enum DownUserLimits : None : Number : [Date] : End Enum Friend Enum DownUserLimits : None : Number : [Date] : End Enum
Private Sub DownloadSelectedUser(ByVal UseLimits As DownUserLimits, Optional ByVal IncludeInTheFeed As Boolean = True) Friend Sub DownloadSelectedUser(ByVal UseLimits As DownUserLimits, Optional ByVal IncludeInTheFeed As Boolean = True,
Optional ByVal SUser As IUserData = Nothing)
Const MsgTitle$ = "Download limit" Const MsgTitle$ = "Download limit"
Dim users As List(Of IUserData) = GetSelectedUserArray() Dim users As List(Of IUserData) = If(SUser Is Nothing, GetSelectedUserArray(), New List(Of IUserData) From {SUser})
If users.ListExists Then If users.ListExists Then
Dim limit%? = Nothing Dim limit%? = Nothing
Dim _from As Date? = Nothing Dim _from As Date? = Nothing
@@ -1699,7 +1709,7 @@ ResumeDownloadingOperation:
$"Do you want to download them all{fStr}?{vbNewLine.StringDup(2)}" & $"Do you want to download them all{fStr}?{vbNewLine.StringDup(2)}" &
$"Selected users:{vbNewLine}{uStr}", "Multiple users selected"}, $"Selected users:{vbNewLine}{uStr}", "Multiple users selected"},
MsgBoxStyle.Question + MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then MsgBoxStyle.Question + MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
users.ForEach(Sub(u) users.ForEach(Sub(ByVal u As IUserData)
u.DownloadTopCount = limit u.DownloadTopCount = limit
u.DownloadDateFrom = _from u.DownloadDateFrom = _from
u.DownloadDateTo = _to u.DownloadDateTo = _to

View File

@@ -26,6 +26,7 @@ Friend Class MainFrameObjects : Implements INotificator
AddHandler .TextAdded, AddressOf ProgramLog_TextAdded AddHandler .TextAdded, AddressOf ProgramLog_TextAdded
AddHandler .TextCleared, AddressOf ProgramLog_TextCleared AddHandler .TextCleared, AddressOf ProgramLog_TextCleared
End With End With
UpdateLogButton()
End Sub End Sub
#Region "Users" #Region "Users"
Friend Sub FocusUser(ByVal Key As String, Optional ByVal ActivateForm As Boolean = False) Friend Sub FocusUser(ByVal Key As String, Optional ByVal ActivateForm As Boolean = False)

View File

@@ -83,6 +83,9 @@ Friend Module MainMod
<Extension> Friend Function ToStringDateDef(ByVal _Date As Date) As String <Extension> Friend Function ToStringDateDef(ByVal _Date As Date) As String
Return ToStringDateDef(_DateN:=_Date) Return ToStringDateDef(_DateN:=_Date)
End Function End Function
<Extension> Friend Function ToDateDef(ByVal DateStr As String, Optional ByVal NothingArg As Object = Nothing) As Object
Return AConvert(Of Date)(DateStr, DateTimeDefaultProvider, NothingArg)
End Function
Friend ReadOnly SessionDateTimeProvider As New ADateTime("yyyyMMdd_HHmmss") Friend ReadOnly SessionDateTimeProvider As New ADateTime("yyyyMMdd_HHmmss")
Friend ReadOnly FeedVideoLengthProvider As New ADateTime("hh\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan} Friend ReadOnly FeedVideoLengthProvider As New ADateTime("hh\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
Friend ReadOnly LogConnector As New LogHost Friend ReadOnly LogConnector As New LogHost

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below: ' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2024.6.10.0")> <Assembly: AssemblyVersion("2024.11.21.0")>
<Assembly: AssemblyFileVersion("2024.6.10.0")> <Assembly: AssemblyFileVersion("2024.11.21.0")>
<Assembly: NeutralResourcesLanguage("en")> <Assembly: NeutralResourcesLanguage("en")>

View File

@@ -150,6 +150,16 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Looks up a localized resource of type System.Drawing.Bitmap.
'''</summary>
Friend ReadOnly Property FindPic_16() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("FindPic_16", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary> '''<summary>
''' Looks up a localized resource of type System.Drawing.Bitmap. ''' Looks up a localized resource of type System.Drawing.Bitmap.
'''</summary> '''</summary>

View File

@@ -223,4 +223,7 @@
<data name="CutPic_48" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="CutPic_48" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Content\Pictures\CutPic_48.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Content\Pictures\CutPic_48.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="FindPic_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Content\Pictures\FindPic_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

View File

@@ -94,14 +94,14 @@ Namespace Plugin.Hosts
HostsUnavailableIndexes = New List(Of Integer) HostsUnavailableIndexes = New List(Of Integer)
Dim defInstance As ISiteSettings = CreateInstance() Dim defInstance As ISiteSettings = CreateInstance()
HostsXml = New List(Of XmlFile) From { HostsXml = New List(Of XmlFile) From {
GetNewXmlFile($"{SettingsFolderName}\{SiteSettingsBase.ResponserFilePrefix}{defInstance.Site}_Settings.xml", defInstance.Site, _XML) GetNewXmlFile($"{SettingsFolderName}\{SiteSettingsBase.ResponserFilePrefix}{defInstance.Site}_Settings.xml")
} }
Hosts = New List(Of SettingsHost) From {New SettingsHost(defInstance, True, HostsXml(0), GlobalPath, _Temp, _Imgs, _Vids)} Hosts = New List(Of SettingsHost) From {New SettingsHost(defInstance, True, HostsXml(0), GlobalPath, _Temp, _Imgs, _Vids)}
Dim hostFiles As List(Of SFile) = SFile.GetFiles(SettingsFolderName.CSFileP, $"{String.Format(FileNamePattern, Key, Name)}*.xml",, EDP.ReturnValue) Dim hostFiles As List(Of SFile) = SFile.GetFiles(SettingsFolderName.CSFileP, $"{String.Format(FileNamePattern, Key, Name)}*.xml",, EDP.ReturnValue)
If hostFiles.ListExists Then If hostFiles.ListExists Then
For Each f As SFile In hostFiles For Each f As SFile In hostFiles
HostsXml.Add(GetNewXmlFile(f, [Default].Name)) HostsXml.Add(GetNewXmlFile(f))
Hosts.Add(New SettingsHost(CreateInstance(HostsXml.Last.Value(SettingsHost.NameXML_AccountName)), False, HostsXml.Last, Hosts.Add(New SettingsHost(CreateInstance(HostsXml.Last.Value(SettingsHost.NameXML_AccountName)), False, HostsXml.Last,
GlobalPath, _Temp, _Imgs, _Vids)) GlobalPath, _Temp, _Imgs, _Vids))
Next Next
@@ -109,30 +109,10 @@ Namespace Plugin.Hosts
Hosts.ListReindex Hosts.ListReindex
Hosts.ForEach(Sub(h) SetHostHandlers(h)) Hosts.ForEach(Sub(h) SetHostHandlers(h))
End Sub End Sub
Private Function GetNewXmlFile(ByVal f As SFile, ByVal SiteName As String, Optional ByVal SourceXml As XmlFile = Nothing) As XmlFile Private Function GetNewXmlFile(ByVal f As SFile) As XmlFile
Dim x As New XmlFile(f,, False) With {.AutoUpdateFile = True} Dim x As New XmlFile(f,, False) With {.AutoUpdateFile = True}
If Not f.Exists Then x.Name = "SiteSettings" If Not f.Exists Then x.Name = "SiteSettings"
x.LoadData() x.LoadData()
'URGENT: reorganization of settings: remove the following code
Dim n$() = {SettingsCLS.Name_Node_Sites, SiteName}
Dim processed As Boolean = False
With If(SourceXml, x)
If .Count > 0 AndAlso .Contains(n) Then
With .Item(n)
If .ListExists Then
For Each container As EContainer In .Self : x.Add(container.Name, container.Value) : Next
processed = True
End If
End With
If processed Then
.Remove(n)
If SourceXml Is Nothing Then .Remove(SettingsCLS.Name_Node_Sites)
x.Name = "SiteSettings"
x.UpdateData()
End If
End If
End With
'-----END REMOVE-----
Return x Return x
End Function End Function
#End Region #End Region
@@ -178,7 +158,7 @@ Namespace Plugin.Hosts
End Sub End Sub
Private Sub Hosts_OkClick(ByVal Obj As SettingsHost) Private Sub Hosts_OkClick(ByVal Obj As SettingsHost)
If Obj.Index = -1 Then If Obj.Index = -1 Then
HostsXml.Add(GetNewXmlFile($"{SettingsFolderName}\{String.Format(FileNamePatternFull, Key, Name, Obj.AccountName)}.xml", Name)) HostsXml.Add(GetNewXmlFile($"{SettingsFolderName}\{String.Format(FileNamePatternFull, Key, Name, Obj.AccountName)}.xml"))
With Settings : Hosts.Add(Obj.Apply(HostsXml.Last, .GlobalPath, With Settings : Hosts.Add(Obj.Apply(HostsXml.Last, .GlobalPath,
.DefaultTemporary, .DefaultDownloadImages, .DefaultDownloadVideos)) : End With .DefaultTemporary, .DefaultDownloadImages, .DefaultDownloadVideos)) : End With
HostsXml.Last.UpdateData() HostsXml.Last.UpdateData()
@@ -355,7 +335,7 @@ Namespace Plugin.Hosts
ByVal ColNameOld As String, ByVal ColNameNew As String) As Boolean ByVal ColNameOld As String, ByVal ColNameNew As String) As Boolean
Dim p As PauseModes = NoPauseMode Dim p As PauseModes = NoPauseMode
Try Try
If UpdateHostPath_CheckDownloader() Then Return False If Not UpdateHostPath_CheckDownloader() Then Return False
If Not AEquals(Of String)(PathOld.PathWithSeparator, PathNew.PathWithSeparator) Or Not AEquals(Of String)(ColNameOld, ColNameNew) Then If Not AEquals(Of String)(PathOld.PathWithSeparator, PathNew.PathWithSeparator) Or Not AEquals(Of String)(ColNameOld, ColNameNew) Then
p = Settings.Automation.Pause p = Settings.Automation.Pause
Settings.Automation.Pause = PauseModes.Unlimited Settings.Automation.Pause = PauseModes.Unlimited
@@ -385,7 +365,7 @@ Namespace Plugin.Hosts
Optional ByVal ForceCollections As Boolean = False) As Boolean Optional ByVal ForceCollections As Boolean = False) As Boolean
Dim p As PauseModes = NoPauseMode Dim p As PauseModes = NoPauseMode
Try Try
If UpdateHostPath_CheckDownloader() Then Return False If Not UpdateHostPath_CheckDownloader() Then Return False
If Not PathNew.IsEmptyString And Settings.UsersList.Count > 0 Then If Not PathNew.IsEmptyString And Settings.UsersList.Count > 0 Then
Dim hp As SFile = Host.Path(False, True) Dim hp As SFile = Host.Path(False, True)
Dim diffPaths As Boolean = (Abs And hp.PathWithSeparator = PathOld.PathWithSeparator) Or Dim diffPaths As Boolean = (Abs And hp.PathWithSeparator = PathOld.PathWithSeparator) Or

View File

@@ -208,11 +208,18 @@
<Compile Include="API\Mastodon\SiteSettings.vb" /> <Compile Include="API\Mastodon\SiteSettings.vb" />
<Compile Include="API\Mastodon\UserData.vb" /> <Compile Include="API\Mastodon\UserData.vb" />
<Compile Include="API\OnlyFans\Declarations.vb" /> <Compile Include="API\OnlyFans\Declarations.vb" />
<Compile Include="API\OnlyFans\DynamicRulesEnv.vb" />
<Compile Include="API\OnlyFans\OFResources.Designer.vb"> <Compile Include="API\OnlyFans\OFResources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>OFResources.resx</DependentUpon> <DependentUpon>OFResources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="API\OnlyFans\OnlyFansAdvancedSettingsForm.Designer.vb">
<DependentUpon>OnlyFansAdvancedSettingsForm.vb</DependentUpon>
</Compile>
<Compile Include="API\OnlyFans\OnlyFansAdvancedSettingsForm.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="API\OnlyFans\SiteSettings.vb" /> <Compile Include="API\OnlyFans\SiteSettings.vb" />
<Compile Include="API\OnlyFans\UserData.vb" /> <Compile Include="API\OnlyFans\UserData.vb" />
<Compile Include="API\OnlyFans\UserExchangeOptions.vb" /> <Compile Include="API\OnlyFans\UserExchangeOptions.vb" />
@@ -542,6 +549,9 @@
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>OFResources.Designer.vb</LastGenOutput> <LastGenOutput>OFResources.Designer.vb</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="API\OnlyFans\OnlyFansAdvancedSettingsForm.resx">
<DependentUpon>OnlyFansAdvancedSettingsForm.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="API\Reddit\RedditViewSettingsForm.resx"> <EmbeddedResource Include="API\Reddit\RedditViewSettingsForm.resx">
<DependentUpon>RedditViewSettingsForm.vb</DependentUpon> <DependentUpon>RedditViewSettingsForm.vb</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
@@ -784,7 +794,11 @@
<None Include="Content\Pictures\SitePictures\FacebookPic_37.png" /> <None Include="Content\Pictures\SitePictures\FacebookPic_37.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="API\OnlyFans\DynamicRules.txt" />
<Content Include="API\OnlyFans\DynamicRulesAll.txt" />
<Content Include="API\OnlyFans\OFScraperConfigPatternConstants.txt" />
<Content Include="Content\Pictures\CutPic_48.png" /> <Content Include="Content\Pictures\CutPic_48.png" />
<Content Include="Content\Pictures\FindPic_16.png" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@@ -10,6 +10,7 @@ Imports PersonalUtilities.Functions.Messaging
Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.XML.Objects Imports PersonalUtilities.Functions.XML.Objects
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls Imports PersonalUtilities.Forms.Controls
Imports PersonalUtilities.Forms.Controls.Base Imports PersonalUtilities.Forms.Controls.Base
Imports PersonalUtilities.Tools Imports PersonalUtilities.Tools
@@ -179,8 +180,12 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property LastCollections As List(Of String) Friend ReadOnly Property LastCollections As List(Of String)
Friend ReadOnly Property DownloadLocations As STDownloader.DownloadLocationsCollection Friend ReadOnly Property DownloadLocations As STDownloader.DownloadLocationsCollection
Friend ReadOnly Property GlobalLocations As STDownloader.DownloadLocationsCollection Friend ReadOnly Property GlobalLocations As STDownloader.DownloadLocationsCollection
#Region "Scheduler"
Friend Property Automation As Scheduler Friend Property Automation As Scheduler
Friend ReadOnly Property AutomationFile As XMLValue(Of String) Friend ReadOnly Property AutomationFile As XMLValue(Of String)
Friend ReadOnly Property AutomationScript As XMLValueUse(Of String)
Friend ReadOnly Property AutomationScript_ExcludeManual As XMLValue(Of Boolean)
#End Region
Friend ReadOnly Property Feeds As FeedSpecialCollection Friend ReadOnly Property Feeds As FeedSpecialCollection
Friend ReadOnly Property BlackList As List(Of UserBan) Friend ReadOnly Property BlackList As List(Of UserBan)
Friend ReadOnly Property Colors As Editors.DataColorCollection Friend ReadOnly Property Colors As Editors.DataColorCollection
@@ -188,6 +193,18 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Private ReadOnly BlackListFile As SFile = $"{SettingsFolderName}\BlackList.txt" Private ReadOnly BlackListFile As SFile = $"{SettingsFolderName}\BlackList.txt"
Private ReadOnly UsersSettingsFile As SFile = $"{SettingsFolderName}\Users.xml" Private ReadOnly UsersSettingsFile As SFile = $"{SettingsFolderName}\Users.xml"
Private ReadOnly Property SettingsVersion As XMLValue(Of Integer) Private ReadOnly Property SettingsVersion As XMLValue(Of Integer)
Private Const SettingsVersionCurrent As Integer = 1
Friend ShortcutOpenFeed As New ButtonKey(Keys.F, True)
Friend ShortcutOpenSearch As New ButtonKey(Keys.F,, True)
Private Sub ChangeFeedOpenMode()
If FeedOpenCtrlF Then
ShortcutOpenFeed = New ButtonKey(Keys.F, True)
ShortcutOpenSearch = New ButtonKey(Keys.F,, True)
Else
ShortcutOpenFeed = New ButtonKey(Keys.F,, True)
ShortcutOpenSearch = New ButtonKey(Keys.F, True)
End If
End Sub
#End Region #End Region
#Region "Initializer" #Region "Initializer"
Friend Sub New() Friend Sub New()
@@ -210,19 +227,16 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Colors = New Editors.DataColorCollection Colors = New Editors.DataColorCollection
EnvironmentProgramsList = New List(Of String) EnvironmentProgramsList = New List(Of String)
AutomationFile = New XMLValue(Of String)("AutomationFile",, MyXML)
SiteSettingsShowHiddenControls = MyXML.Value("SiteSettingsShowHiddenControls").FromXML(Of Boolean)(False)
Dim n() As String
Dim n_old() As String 'URGENT: remove this line
Dim rn As Boolean = Not MyXML.File.Exists
SettingsReoranized = New XMLValue(Of Boolean)("SettingsReoranized", rn, MyXML) 'URGENT: remove this line
SettingsReoranized2 = New XMLValue(Of Boolean)("SettingsReoranized2", rn, MyXML) 'URGENT: remove this line
Dim forceSaveXML As Boolean = Not SettingsReoranized 'URGENT: remove this line
Dim forceSaveXML2 As Boolean = Not SettingsReoranized OrElse Not SettingsReoranized2 'URGENT: remove this line
SettingsVersion = New XMLValue(Of Integer)("SettingsVersion", 0, MyXML) SettingsVersion = New XMLValue(Of Integer)("SettingsVersion", 0, MyXML)
Dim n() As String = {"Scheduler"}
AutomationFile = New XMLValue(Of String)("File",, MyXML, n)
If SettingsVersion.Value = 0 AndAlso MyXML.Contains(AutomationFile.Name) Then AutomationFile.Value = MyXML.Value(AutomationFile.Name)
AutomationScript = New XMLValueUse(Of String)("Script", String.Empty,, MyXML, n)
AutomationScript_ExcludeManual = New XMLValue(Of Boolean)("ScriptExcludeManual", True, MyXML, n)
SiteSettingsShowHiddenControls = MyXML.Value("SiteSettingsShowHiddenControls").FromXML(Of Boolean)(False)
#Region "Properties: environment" #Region "Properties: environment"
'Environment 'Environment
n = {"MediaEnvironment"} n = {"MediaEnvironment"}
@@ -251,7 +265,6 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
CollectionsPath = New XMLValue(Of String)("CollectionsPath", CollectionsFolderName, MyXML, n) CollectionsPath = New XMLValue(Of String)("CollectionsPath", CollectionsFolderName, MyXML, n)
MaxUsersJobsCount = New XMLValue(Of Integer)("MaxJobsCount", DefaultMaxDownloadingTasks, MyXML, n) MaxUsersJobsCount = New XMLValue(Of Integer)("MaxJobsCount", DefaultMaxDownloadingTasks, MyXML, n)
UserAgent = New XMLValue(Of String)("UserAgent",, MyXML, n) UserAgent = New XMLValue(Of String)("UserAgent",, MyXML, n)
If Not SettingsReoranized Then UserAgent.Value = New XMLValue(Of String)("UserAgent",, MyXML).Value 'URGENT: remove this line
ImgurClientID = New XMLValue(Of String)("ImgurClientID", String.Empty, MyXML, {Name_Node_Sites}) ImgurClientID = New XMLValue(Of String)("ImgurClientID", String.Empty, MyXML, {Name_Node_Sites})
'Basis: new version 'Basis: new version
@@ -294,17 +307,13 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
DownloadOpenInfo = New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenInfo", "OpenAgain", False, False, MyXML, n) DownloadOpenInfo = New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenInfo", "OpenAgain", False, False, MyXML, n)
DownloadOpenProgress = New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenProgress", "OpenAgain", False, False, MyXML, n) DownloadOpenProgress = New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenProgress", "OpenAgain", False, False, MyXML, n)
ClosingCommand = New XMLValueAttribute(Of String, Boolean)("ClosingCommand", "Use",,, MyXML, n) ClosingCommand = New XMLValueAttribute(Of String, Boolean)("ClosingCommand", "Use",,, MyXML, n)
'URGENT: remove these lines
If Not SettingsReoranized Then
With New XMLValueAttribute(Of String, Boolean)("ClosingCommand", "Use",,, MyXML)
ClosingCommand.Value = .Value
ClosingCommand.AttributeValue = .AttributeValue
End With
End If
AddHandler ClosingCommand.ValueChanged, Sub(s, ev) MainFrameObj?.ChangeCloseVisible() AddHandler ClosingCommand.ValueChanged, Sub(s, ev) MainFrameObj?.ChangeCloseVisible()
DownloadAll_UseF6 = New XMLValue(Of Boolean)("DownloadAll_UseF6", True, MyXML, n) DownloadAll_UseF6 = New XMLValue(Of Boolean)("DownloadAll_UseF6", True, MyXML, n)
DownloadAll_UseF6_Confirm = New XMLValue(Of Boolean)("DownloadAll_UseF6_Confirm", False, MyXML, n) DownloadAll_UseF6_Confirm = New XMLValue(Of Boolean)("DownloadAll_UseF6_Confirm", False, MyXML, n)
DownloadAll_Confirm = New XMLValue(Of Boolean)("DownloadAll_Confirm", False, MyXML, n) DownloadAll_Confirm = New XMLValue(Of Boolean)("DownloadAll_Confirm", False, MyXML, n)
FeedOpenCtrlF = New XMLValue(Of Boolean)("FeedOpenCtrlF", True, MyXML, n)
AddHandler FeedOpenCtrlF.ValueChanged, AddressOf ChangeFeedOpenMode
ChangeFeedOpenMode()
'Notifications 'Notifications
n = {"Notifications"} n = {"Notifications"}
@@ -359,19 +368,14 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
AutomationBrushUndownloadedPlansMinutes = New XMLValue(Of Integer)("AutomationBrushUndownloadedPlansMinutes", 10080, MyXML, n) AutomationBrushUndownloadedPlansMinutes = New XMLValue(Of Integer)("AutomationBrushUndownloadedPlansMinutes", 10080, MyXML, n)
'Downloading: file naming 'Downloading: file naming
n_old = {"Users", "FileName"}
n = {"Downloading", "FileName"} n = {"Downloading", "FileName"}
FileAddDateToFileName = New XMLValue(Of Boolean)("FileAddDateToFileName", False, MyXML, n) FileAddDateToFileName = New XMLValue(Of Boolean)("FileAddDateToFileName", False, MyXML, n)
If Not SettingsReoranized Then FileAddDateToFileName.Value = New XMLValue(Of Boolean)("FileAddDateToFileName", False, MyXML, n_old).Value 'URGENT: remove this line
AddHandler FileAddDateToFileName.ValueChanged, AddressOf ChangeDateProvider AddHandler FileAddDateToFileName.ValueChanged, AddressOf ChangeDateProvider
FileAddTimeToFileName = New XMLValue(Of Boolean)("FileAddTimeToFileName", False, MyXML, n) FileAddTimeToFileName = New XMLValue(Of Boolean)("FileAddTimeToFileName", False, MyXML, n)
If Not SettingsReoranized Then FileAddTimeToFileName.Value = New XMLValue(Of Boolean)("FileAddTimeToFileName", False, MyXML, n_old).Value 'URGENT: remove this line
AddHandler FileAddTimeToFileName.ValueChanged, AddressOf ChangeDateProvider AddHandler FileAddTimeToFileName.ValueChanged, AddressOf ChangeDateProvider
FileDateTimePositionEnd = New XMLValue(Of Boolean)("FileDateTimePositionEnd", True, MyXML, n) FileDateTimePositionEnd = New XMLValue(Of Boolean)("FileDateTimePositionEnd", True, MyXML, n)
If Not SettingsReoranized Then FileDateTimePositionEnd.Value = New XMLValue(Of Boolean)("FileDateTimePositionEnd", True, MyXML, n_old).Value 'URGENT: remove this line
AddHandler FileDateTimePositionEnd.ValueChanged, AddressOf ChangeDateProvider AddHandler FileDateTimePositionEnd.ValueChanged, AddressOf ChangeDateProvider
FileReplaceNameByDate = New XMLValue(Of Integer)("FileReplaceNameByDate", FileNameReplaceMode.None, MyXML, n) FileReplaceNameByDate = New XMLValue(Of Integer)("FileReplaceNameByDate", FileNameReplaceMode.None, MyXML, n)
If Not SettingsReoranized Then FileReplaceNameByDate.Value = New XMLValue(Of Integer)("FileReplaceNameByDate", FileNameReplaceMode.None, MyXML, n_old).Value 'URGENT: remove this line
'Downloading: script 'Downloading: script
n = {"Downloading", "Script"} n = {"Downloading", "Script"}
@@ -412,6 +416,9 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
FeedLastModeSubscriptions = New XMLValue(Of Boolean)("LastModeSubscriptions", False, MyXML, n) FeedLastModeSubscriptions = New XMLValue(Of Boolean)("LastModeSubscriptions", False, MyXML, n)
FeedShowFriendlyNames = New XMLValue(Of Boolean)("ShowFriendlyNames", True, MyXML, n) FeedShowFriendlyNames = New XMLValue(Of Boolean)("ShowFriendlyNames", True, MyXML, n)
FeedShowSpecialFeedsMediaItem = New XMLValue(Of Boolean)("ShowSpecialFeedsMediaItem", False, MyXML, n) FeedShowSpecialFeedsMediaItem = New XMLValue(Of Boolean)("ShowSpecialFeedsMediaItem", False, MyXML, n)
FeedEscToClose = New XMLValue(Of Boolean)("EscToClose", True, MyXML, n)
FeedSpecialSearchForMissing = New XMLValue(Of Boolean)("FeedSpecialSearchForMissing", True, MyXML, n)
FeedSpecialSearchForMissing_Deep = New XMLValue(Of Boolean)("FeedSpecialSearchForMissing_Deep", False, MyXML, n)
n = {"Feed", "MoveCopy"} n = {"Feed", "MoveCopy"}
FeedMoveCopyLastLocation = New XMLValue(Of SFile)("LastLocation",, MyXML, n) FeedMoveCopyLastLocation = New XMLValue(Of SFile)("LastLocation",, MyXML, n)
FeedMoveCopyUpdateFileLocationOnMove = New XMLValue(Of Boolean)("UpdateFileLocationOnMove", True, MyXML, n) FeedMoveCopyUpdateFileLocationOnMove = New XMLValue(Of Boolean)("UpdateFileLocationOnMove", True, MyXML, n)
@@ -451,7 +458,6 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
LatestSavingPath = New XMLValue(Of SFile)("LatestSavingPath", Nothing, MyXML, n, New XMLToFilePathProvider) LatestSavingPath = New XMLValue(Of SFile)("LatestSavingPath", Nothing, MyXML, n, New XMLToFilePathProvider)
LatestSelectedChannel = New XMLValue(Of String)("LatestSelectedChannel",, MyXML, n) LatestSelectedChannel = New XMLValue(Of String)("LatestSelectedChannel",, MyXML, n)
#End Region #End Region
ReorganizeSettingsFile()
#Region "Loading plugins" #Region "Loading plugins"
Plugins.AddRange(PluginHost.GetMyHosts(MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)) Plugins.AddRange(PluginHost.GetMyHosts(MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos))
Dim tmpPluginList As IEnumerable(Of PluginHost) = PluginHost.GetPluginsHosts(MyXML, GlobalPath.Value, DefaultTemporary, Dim tmpPluginList As IEnumerable(Of PluginHost) = PluginHost.GetPluginsHosts(MyXML, GlobalPath.Value, DefaultTemporary,
@@ -475,7 +481,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
UpdatePluginsUserAgent(False) UpdatePluginsUserAgent(False)
#End Region #End Region
Labels = New LabelsKeeper(MyXML) Labels = New LabelsKeeper
Groups = New Groups.DownloadGroupCollection Groups = New Groups.DownloadGroupCollection
Labels.AddRange(Groups.GetGroupsLabels, False) Labels.AddRange(Groups.GetGroupsLabels, False)
AdvancedFilter = New Groups.DownloadGroup(False) With {.IsViewFilter = True} AdvancedFilter = New Groups.DownloadGroup(False) With {.IsViewFilter = True}
@@ -483,61 +489,10 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
AdvancedFilter.IsViewFilter = True AdvancedFilter.IsViewFilter = True
Labels.AddRange({AdvancedFilter}.GetGroupsLabels, False) Labels.AddRange({AdvancedFilter}.GetGroupsLabels, False)
'URGENT: remove this code (2024.03) SettingsVersion.Value = SettingsVersionCurrent
#Region "To delete"
'delete this property:
ViewReorganized = New XMLValue(Of Boolean)("ViewReorganized", rn, MyXML)
If Not ViewReorganized.Value Then
ViewReorganized.Value = True
Dim oldShowMode% = MyXML.Value("ShowingMode").FromXML(Of Integer)(0)
Dim MainFrameUsersShowDefaults As Boolean = MyXML.Value("UsersShowDefaults").FromXML(Of Boolean)(True)
Dim MainFrameUsersShowSubscriptions As Boolean = MyXML.Value("UsersShowSubscriptions").FromXML(Of Boolean)(True)
ShowAllUsers.Value = oldShowMode = 0 And MainFrameUsersShowDefaults And MainFrameUsersShowSubscriptions
Dim ViewDateMode As New XMLValue(Of Integer)("ViewDateMode", ShowingDates.Off, MyXML)
Dim SelectedSites As New XMLValuesCollection(Of String)(IXMLValuesCollection.Modes.String, "SelectedSites",, MyXML, {Name_Node_Sites})
If Not ShowAllUsers Or SelectedSites.Count > 0 Or Not ViewDateMode.Value = ShowingDates.Off Then
ShowAllUsers.Value = False
With AdvancedFilter
.DownloadUsers = MainFrameUsersShowDefaults
.DownloadSubscriptions = MainFrameUsersShowSubscriptions
If SelectedSites.Count > 0 Then .Sites.AddRange(SelectedSites)
#Disable Warning BC40008
Select Case oldShowMode
Case 20 : .Regular = True : .Temporary = False : .Favorite = False
Case 50 : .Regular = False : .Temporary = True : .Favorite = False
Case 100 : .Regular = False : .Temporary = False : .Favorite = True
Case 500 : If Labels.Current.Count > 0 Then .Labels.Clear() : .Labels.AddRange(Labels.Current)
Case 1000 : .LabelsNo = True
Case 10000 : .UserExists = False : .UserDeleted = True : .UserSuspended = False
Case 12000 : .UserExists = False : .UserDeleted = False : .UserSuspended = True
End Select
If Labels.Excluded.Count > 0 Then .LabelsExcluded.AddRange(Labels.Excluded)
.LabelsExcludedIgnore = Labels.ExcludedIgnore
#Enable Warning
Dim _ViewDateFrom As New XMLValue(Of Date)
_ViewDateFrom.SetExtended("ViewDateFrom",, MyXML)
Dim _ViewDateTo As New XMLValue(Of Date)
_ViewDateTo.SetExtended("ViewDateTo",, MyXML)
If Not ViewDateMode.Value = ShowingDates.Off Then
.DateMode = ViewDateMode
If _ViewDateFrom.Exists Then .DateFrom = _ViewDateFrom.Value Else .DateFrom = Nothing
If _ViewDateTo.Exists Then .DateTo = _ViewDateTo.Value Else .DateTo = Nothing
End If
_ViewDateFrom.Dispose()
_ViewDateTo.Dispose()
.UpdateFile()
End With
End If
ViewDateMode.Dispose()
SelectedSites.Dispose()
End If
#End Region
If Not forceSaveXML And forceSaveXML2 Then SettingsReoranized2.Value = True
MyXML.EndUpdate() MyXML.EndUpdate()
If MyXML.ChangesDetected Or forceSaveXML Or forceSaveXML2 Then MyXML.Sort() : MyXML.UpdateData() If MyXML.ChangesDetected Then MyXML.Sort() : MyXML.UpdateData()
If BlackListFile.Exists Then If BlackListFile.Exists Then
BlackList.ListAddList(IO.File.ReadAllLines(BlackListFile), LAP.NotContainsOnly) BlackList.ListAddList(IO.File.ReadAllLines(BlackListFile), LAP.NotContainsOnly)
@@ -546,107 +501,6 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
_UpdatesSuspended = False _UpdatesSuspended = False
ChangeDateProvider(Nothing, Nothing) ChangeDateProvider(Nothing, Nothing)
End Sub End Sub
#End Region
'URGENT: remove 'Reorganize' code (2024.03)
#Region "Reorganize"
Private Property SettingsReoranized As XMLValue(Of Boolean)
Private Property SettingsReoranized2 As XMLValue(Of Boolean)
Private Sub ReorganizeSettingsFile()
If Not SettingsReoranized Then
SettingsReoranized.Value = True
Dim n$()
GlobalPath.Value = New XMLValue(Of SFile)("GlobalPath", "Data\".CSFileP, MyXML,, New XMLToFilePathProvider).Value
MaxLargeImageHeight.Value = New XMLValue(Of Integer)("MaxLargeImageHeight", 150, MyXML).Value
MaxSmallImageHeight.Value = New XMLValue(Of Integer)("MaxSmallImageHeight", 15, MyXML).Value
CollectionsPath.Value = New XMLValue(Of String)("CollectionsPath", CollectionsFolderName, MyXML).Value
MaxUsersJobsCount.Value = New XMLValue(Of Integer)("MaxJobsCount", DefaultMaxDownloadingTasks, MyXML, {"Users", "FileName"}).Value
CheckUpdatesAtStart.Value = New XMLValue(Of Boolean)("CheckUpdatesAtStart", True, MyXML).Value
ShowNewVersionNotification.Value = New XMLValue(Of Boolean)("ShowNewVersionNotification", True, MyXML).Value
LatestVersion.Value = New XMLValue(Of String)("LatestVersion", String.Empty, MyXML).Value
ProgramText.Value = New XMLValue(Of String)("ProgramText",, MyXML).Value
ProgramDescription.Value = New XMLValue(Of String)("ProgramDescription",, MyXML).Value
UserListImage.Value = New XMLValue(Of SFile)("UserListImage",, MyXML).Value
Dim __UserListBackColor As New XMLValue(Of Color)
__UserListBackColor.SetExtended("UserListBackColor",, MyXML)
UserListBackColor.ValueF = __UserListBackColor.ValueF
Dim __UserListForeColor As New XMLValue(Of Color)
__UserListForeColor.SetExtended("UserListForeColor",, MyXML)
UserListForeColor.ValueF = __UserListForeColor.ValueF
MainFrameUsersSubscriptionsColorBack.Value = New XMLValue(Of Color)("UsersSubscriptionsColorBack", MyColor.OkBack, MyXML).Value
MainFrameUsersSubscriptionsColorFore.Value = New XMLValue(Of Color)("UsersSubscriptionsColorFore", MyColor.OkFore, MyXML).Value
Dim __MainFrameUsersSubscriptionsColorBack_USERS As New XMLValue(Of Color)
__MainFrameUsersSubscriptionsColorBack_USERS.SetExtended("UsersSubscriptionsColorBack_USERS",, MyXML)
MainFrameUsersSubscriptionsColorBack_USERS.ValueF = __MainFrameUsersSubscriptionsColorBack_USERS.ValueF
Dim __MainFrameUsersSubscriptionsColorFore_USERS As New XMLValue(Of Color)
__MainFrameUsersSubscriptionsColorFore_USERS.SetExtended("UsersSubscriptionsColorFore_USERS",, MyXML)
MainFrameUsersSubscriptionsColorFore_USERS.ValueF = __MainFrameUsersSubscriptionsColorFore_USERS.ValueF
CMDEncoding.Value = New XMLValue(Of Integer)("CMDEncoding", DefaultCmdEncoding, MyXML, {"Defaults"}).Value
ExitConfirm.Value = New XMLValue(Of Boolean)("ExitConfirm", True, MyXML).Value
CloseToTray.Value = New XMLValue(Of Boolean)("CloseToTray", True, MyXML).Value
With New XMLValueUse(Of String)("OpenFolderInOtherProgram",,, MyXML)
OpenFolderInOtherProgram.Value = .Value
OpenFolderInOtherProgram.Use = .Use
End With
DeleteToRecycleBin.Value = New XMLValue(Of Boolean)("DeleteToRecycleBin", True, MyXML).Value
FastProfilesLoading.Value = New XMLValue(Of Boolean)("FastProfilesLoading", True, MyXML).Value
With New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenInfo", "OpenAgain", False, False, MyXML)
DownloadOpenInfo.Value = .Value
DownloadOpenInfo.AttributeValue = .AttributeValue
End With
With New XMLValueAttribute(Of Boolean, Boolean)("DownloadOpenProgress", "OpenAgain", False, False, MyXML)
DownloadOpenProgress.Value = .Value
DownloadOpenProgress.AttributeValue = .AttributeValue
End With
SeparateVideoFolder.Value = New XMLValue(Of Boolean)("SeparateVideoFolder", True, MyXML).Value
AddMissingToLog.Value = New XMLValue(Of Boolean)("AddMissingToLog", True, MyXML).Value
AddMissingErrorsToLog.Value = New XMLValue(Of Boolean)("AddMissingErrorsToLog", False, MyXML).Value
With New XMLValueAttribute(Of String, Boolean)("DownloadsCompleteCommand", "Use",,, MyXML)
DownloadsCompleteCommand.Value = .Value
DownloadsCompleteCommand.AttributeValue = .AttributeValue
End With
n = {"Users"}
UpdateUserDescriptionEveryTime.Value = New XMLValue(Of Boolean)("UpdateUserDescriptionEveryTime", True, MyXML, n).Value
UpdateUserIconBannerEveryTime.Value = New XMLValue(Of Boolean)("UpdateUserIconBannerEveryTime", True, MyXML, n).Value
n = {"Defaults"}
UpdateUserSiteNameEveryTime.Value = New XMLValue(Of Boolean)("UserSiteNameUpdateEveryTime", False, MyXML, n).Value
ReparseMissingInTheRoutine.Value = New XMLValue(Of Boolean)("ReparseMissingInTheRoutine", False, MyXML, n).Value
UseDefaultAccountIfMissing.Value = New XMLValue(Of Boolean)("UseDefaultAccountIfMissing", True, MyXML, n).Value
n = {"Users"}
FromChannelDownloadTop.Value = New XMLValue(Of Integer)("FromChannelDownloadTop", 10, MyXML, n).Value
FromChannelDownloadTopUse.Value = New XMLValue(Of Boolean)("FromChannelDownloadTopUse", False, MyXML, n).Value
FromChannelCopyImageToUser.Value = New XMLValue(Of Boolean)("FromChannelCopyImageToUser", True, MyXML, n).Value
With New XMLValueAttribute(Of String, Boolean)("ScriptData", "Use",,, MyXML, n)
ScriptData.Value = .Value
ScriptData.AttributeValue = .AttributeValue
End With
ViewMode.Value = New XMLValue(Of Integer)("ViewMode", ViewModes.IconLarge, MyXML).Value
GroupUsers.Value = New XMLValue(Of Boolean)("UseGrouping", True, MyXML).Value
ShowGroupsInsteadLabels.Value = New XMLValue(Of Boolean)("ShowGroupsInsteadLabels", False, MyXML).Value
InfoViewMode.Value = New XMLValue(Of Integer)("InfoViewMode", DownloadObjects.DownloadedInfoForm.ViewModes.Session, MyXML).Value
InfoViewDefault.Value = New XMLValue(Of Boolean)("InfoViewDefault", True, MyXML).Value
LatestSavingPath.Value = New XMLValue(Of SFile)("LatestSavingPath", Nothing, MyXML,, New XMLToFilePathProvider).Value
LatestSelectedChannel.Value = New XMLValue(Of String)("LatestSelectedChannel",, MyXML).Value
LastCopyPath.Value = New XMLValue(Of SFile)("LastCopyPath",, MyXML,, New XMLToFilePathProvider).Value
End If
End Sub
#End Region #End Region
#Region "Users" #Region "Users"
Friend Sub LoadUsers() Friend Sub LoadUsers()
@@ -1086,6 +940,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property DownloadAll_UseF6 As XMLValue(Of Boolean) Friend ReadOnly Property DownloadAll_UseF6 As XMLValue(Of Boolean)
Friend ReadOnly Property DownloadAll_UseF6_Confirm As XMLValue(Of Boolean) Friend ReadOnly Property DownloadAll_UseF6_Confirm As XMLValue(Of Boolean)
Friend ReadOnly Property DownloadAll_Confirm As XMLValue(Of Boolean) Friend ReadOnly Property DownloadAll_Confirm As XMLValue(Of Boolean)
Friend ReadOnly Property FeedOpenCtrlF As XMLValue(Of Boolean)
#End Region #End Region
#Region "Notifications" #Region "Notifications"
Friend Enum NotificationObjects Friend Enum NotificationObjects
@@ -1272,6 +1127,9 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property FeedLastModeSubscriptions As XMLValue(Of Boolean) Friend ReadOnly Property FeedLastModeSubscriptions As XMLValue(Of Boolean)
Friend ReadOnly Property FeedShowFriendlyNames As XMLValue(Of Boolean) Friend ReadOnly Property FeedShowFriendlyNames As XMLValue(Of Boolean)
Friend ReadOnly Property FeedShowSpecialFeedsMediaItem As XMLValue(Of Boolean) Friend ReadOnly Property FeedShowSpecialFeedsMediaItem As XMLValue(Of Boolean)
Friend ReadOnly Property FeedEscToClose As XMLValue(Of Boolean)
Friend ReadOnly Property FeedSpecialSearchForMissing As XMLValue(Of Boolean)
Friend ReadOnly Property FeedSpecialSearchForMissing_Deep As XMLValue(Of Boolean)
#Region "MoveCopy" #Region "MoveCopy"
Friend ReadOnly Property FeedMoveCopyLastLocation As XMLValue(Of SFile) Friend ReadOnly Property FeedMoveCopyLastLocation As XMLValue(Of SFile)
Friend ReadOnly Property FeedMoveCopyUpdateFileLocationOnMove As XMLValue(Of Boolean) Friend ReadOnly Property FeedMoveCopyUpdateFileLocationOnMove As XMLValue(Of Boolean)
@@ -1292,7 +1150,6 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
End Get End Get
End Property End Property
Friend ReadOnly Property ShowAllUsers As XMLValue(Of Boolean) Friend ReadOnly Property ShowAllUsers As XMLValue(Of Boolean)
Private ReadOnly Property ViewReorganized As XMLValue(Of Boolean)
Friend ReadOnly Property GroupUsers As XMLValue(Of Boolean) Friend ReadOnly Property GroupUsers As XMLValue(Of Boolean)
Friend ReadOnly Property ShowGroupsInsteadLabels As XMLValue(Of Boolean) Friend ReadOnly Property ShowGroupsInsteadLabels As XMLValue(Of Boolean)
#End Region #End Region

View File

@@ -13,6 +13,25 @@ Friend Class UserImage : Inherits ImageRenderer
Friend Const ImagePostfix_Small As String = "_Small" Friend Const ImagePostfix_Small As String = "_Small"
Private _LargeAddress As SFile Private _LargeAddress As SFile
Private _SmallAddress As SFile Private _SmallAddress As SFile
Private _ForceSaveOrig As Boolean = False
Friend Shared Function NewUserPicture(ByVal ImageOrig As SFile, ByVal Destination As SFile,
Optional ByVal Save As Boolean = True, Optional ByVal GetInstance As Boolean = False) As UserImage
Dim uImg As New UserImage(ImageOrig, Destination)
With uImg
._ForceSaveOrig = ImageOrig.Extension.IsEmptyString OrElse ImageOrig.Extension.ToLower = "gif" OrElse Not {"jpg", "jpeg", "png"}.Contains(ImageOrig.Extension.ToLower)
If Not ._ForceSaveOrig Then
If .Address.Exists AndAlso Not .Address.Delete(SFO.File,, EDP.ReturnValue) Then ._ForceSaveOrig = True
If Not ._ForceSaveOrig AndAlso Not ImageOrig.Copy(.Address) Then ._ForceSaveOrig = True
End If
If Not ._ForceSaveOrig Then
._SmallAddress.Extension = .Address.Extension
._LargeAddress.Extension = .Address.Extension
End If
If Save Then .Save()
End With
If Not GetInstance Then uImg.Dispose() : uImg = Nothing
Return uImg
End Function
Friend Sub New(ByVal _ImgOriginal As SFile, ByVal Destination As SFile, Optional ByVal GenerateLargeSmallPictures As Boolean = True) Friend Sub New(ByVal _ImgOriginal As SFile, ByVal Destination As SFile, Optional ByVal GenerateLargeSmallPictures As Boolean = True)
MyBase.New(_ImgOriginal) MyBase.New(_ImgOriginal)
Dim f As SFile = Destination Dim f As SFile = Destination
@@ -71,7 +90,7 @@ Friend Class UserImage : Inherits ImageRenderer
End With End With
End Function End Function
Public Overrides Sub Save() Public Overrides Sub Save()
MyBase.Save() If _ForceSaveOrig Then MyBase.Save()
Small.Save(_SmallAddress) Small.Save(_SmallAddress)
Large.Save(_LargeAddress) Large.Save(_LargeAddress)
End Sub End Sub

View File

@@ -4,4 +4,8 @@ REM Replace 'd:\Downloads\SocialNetworks\' with the path to your SCrawler data f
REM THIS SCRIPT IS NOT SUITABLE FOR 7ZIP OR OTHER ARCHIVING PROGRAMS. REM THIS SCRIPT IS NOT SUITABLE FOR 7ZIP OR OTHER ARCHIVING PROGRAMS.
REM But I believe 7Zip also has CLI commands REM But I believe 7Zip also has CLI commands
"C:\Program Files\WinRAR\WinRAR.exe" a -r -ep1 -o+ -ag_YYYYMMDD_HHMMSS -m5 -tl -n*.txt -n*.xml "d:\Downloads\SocialNetworks\SCrawlerBackup.rar" "d:\Downloads\SocialNetworks\" REM This line archives SCrawler settings files.
"C:\Program Files\WinRAR\WinRAR.exe" a -r -ep1 -o+ -ag_YYYYMMDD_HHMMSS -m5 -tl "D:\MyPrograms\SCrawler\Backup\Settings.rar" "D:\MyPrograms\SCrawler\Settings\"
REM This line archives SCrawler users' settings files.
"C:\Program Files\WinRAR\WinRAR.exe" a -r -ep1 -o+ -ag_YYYYMMDD_HHMMSS -m5 -tl -n*.txt -n*.xml "D:\MyPrograms\SCrawler\Backup\SCrawlerBackup.rar" "D:\MyPrograms\SCrawler\Data\"