mirror of
https://github.com/AAndyProgram/SCrawler.git
synced 2026-03-14 15:52:18 +00:00
2.0.0.2
Site settings have been expanded, some functions and dependencies have been changed. Removed unused elements in UserDataBase, added additional xml fields, added error executor. Created a basic download function. Added Instagram saved posts and 429 bypass. Added channel statistics. Added site redgifs. Updated sites algorithms. Other improvements. Updated downloader algorithm.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Contributor's Guide
|
||||
|
||||
I welcome pull requests! Follow these steps to contribute:
|
||||
I welcome requests! Follow these steps to contribute:
|
||||
|
||||
1. Find an [issue](https://github.com/AAndyProgram/SCrawler/issues) that needs assistance.
|
||||
2. Let me know you are working on it by posting a comment on the issue.
|
||||
@@ -21,11 +21,22 @@ I welcome pull requests! Follow these steps to contribute:
|
||||
2. 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).
|
||||
- If I'm interested in a site you want to add, it may be added in future releases.
|
||||
- If the site has an API that does not require authorization, it may be added in the coming releases.
|
||||
- You can make it faster by posting a link to the API. I don't use OAuth authentication in my application, so if it's not too hard to make a new parsing algorithm without OAuth authorization, I can start developing it in the coming days. Otherwise, I need time to figure out how to do it.
|
||||
- You can make it faster by posting a link to the API. **I don't use OAuth authentication** in my application, so if it's not too hard to make a new parsing algorithm **without OAuth** authorization, I can start developing it in the coming days. Otherwise, I need time to figure out how to do it.
|
||||
- If the site does not have an API that does not require authorization, this may take some time.
|
||||
- If you will be posting request urls **without OAuth** authentication, I might consider adding your site if I have time.
|
||||
- If I'm **not** interested in the site you want to add, you can pay to have it added by making a donation of approximately $10. **But before that, you still need to create an issue. If I'm not interested, you can offer me a deal to develop it for money. I'll check the site you want to add, check the availability of the API and tell you how much time I need to develop it and the price. If you agree, I will do it.** [](https://ko-fi.com/andyprogram)
|
||||
|
||||
|
||||
# Sites I will never develop
|
||||
|
||||
- Facebook
|
||||
|
||||
# Sites requested by users
|
||||
|
||||
- TikTok
|
||||
- API for receiving data without authorization was not found. Therefore, I don't have time to start developing this site parsing algorithm. If anyone knows of requests that may collect data without OAuth authentication, please let me know.
|
||||
|
||||
# Contact me
|
||||
|
||||
[Element messenger](https://element.io/): @andyprogram:matrix.org
|
||||
https://matrix.to/#/@andyprogram:matrix.org
|
||||
22
Changelog.md
22
Changelog.md
@@ -1,3 +1,25 @@
|
||||
# 2.0.0.2
|
||||
|
||||
**This is the last release that supports program settings of version 1.0.0.4 and lower. Compatibility of program settings with version 1.0.0.4 and lower will be removed in future releases. It is strongly recommended that you upgrade to this release before future releases. Otherwise, you will have to configure the program settings again. If your program version is 1.0.1.0 or higher, you should not pay attention to this message.**
|
||||
|
||||
- Added
|
||||
- Tray icon
|
||||
- Close program to tray
|
||||
- Close confirmation dialog
|
||||
- **Separated thread for downloading Instagram profiles**
|
||||
- **Wait timers to bypass Instagram error "Too Many Requests" (429)**
|
||||
- **Downloading saved Instagram posts** *(requires a second InstaHash)*
|
||||
- Downloading saved posts (from Reddit and Instagram) form
|
||||
- Tray notification when download is complete (Instagram notification separate from other)
|
||||
- Downloading not downloaded Instagram posts when a 429 error is encountered and/or the user stops downloading
|
||||
- Separate progress bar for downloading Instagram profiles
|
||||
- Clear information about downloaded profiles of the current session in the "Download info form"
|
||||
- Increased the number of Instagram posts (from 12 to 50) received per request
|
||||
- Channels' statistics
|
||||
- **RedGisf profiles support**
|
||||
- Fixed
|
||||
- The program was showing incorrect information about the total numbers of images and videos downloaded when a Reddit user was created from a channel
|
||||
|
||||
# 2.0.0.1
|
||||
|
||||
- Added
|
||||
|
||||
23
README.md
23
README.md
@@ -1,6 +1,6 @@
|
||||
# Social networks crawler
|
||||
|
||||
Program for downloading photo and video from Reddit, Twitter and Instagram
|
||||
A program to download photo and video from Reddit, Twitter, Instagram, [etc](#supported-sites).
|
||||
|
||||
Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :)
|
||||
|
||||
@@ -11,23 +11,30 @@ Do you like this program? Consider adding to my coffee fund by making a donation
|
||||
- Reddit images;
|
||||
- Reddit galleries of images;
|
||||
- Redgifs hosted videos (https://www.redgifs.com/);
|
||||
- Reddit hosted videos (downloading Reddit hosted video is going through ffmpeg);
|
||||
- Reddit hosted videos (downloading Reddit hosted video is going through ffmpeg (**ffmpeg only works with the x64 program**));
|
||||
- Twitter images and videos;
|
||||
- Instagram images and videos.
|
||||
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels).
|
||||
- Download [saved Reddit posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts).
|
||||
- Download [saved Reddit and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts).
|
||||
- Add users from parsed channel.
|
||||
- Labeling users.
|
||||
- Filter exists users by label or group.
|
||||
- Selection of media types you want to download (images only, videos only, both)
|
||||
|
||||
# Supported sites
|
||||
|
||||
- Reddit
|
||||
- Twitter
|
||||
- Instagram
|
||||
- RedGifs
|
||||
|
||||
# How does it works:
|
||||
|
||||
## Reddit
|
||||
|
||||
The program parses all user posts, obtain MD5 images hash and compares them with existing ones to remove duplicates. Then the media will be downloaded.
|
||||
|
||||
## Twitter and Instagram
|
||||
## Other sites
|
||||
|
||||
The program parses all user posts and compares file names with existing ones to remove duplicates. Then the media will be downloaded.
|
||||
|
||||
@@ -42,7 +49,7 @@ Read [here](https://github.com/AAndyProgram/SCrawler/blob/main/CONTRIBUTING.md#h
|
||||
- Windows 7, 8, 9, 10, 11 with NET Framework 4.6.1 or higher
|
||||
- Authorization cookies and tokens for Twitter (if you want to download data from Twitter)
|
||||
- Authorization cookies Instagram (if you want to download data from Instagram)
|
||||
- ffmpeg library for downloading videos hosted on Reddit (you can download it from the [official repo](https://github.com/GyanD/codexffmpeg/releases/tag/2021-01-12-git-ca21cb1e36) or [from my first release](https://github.com/AAndyProgram/SCrawler/releases/download/1.0.0.0/ffmpeg.zip))
|
||||
- ffmpeg library for downloading videos hosted on Reddit (you can download it from the [official repo](https://github.com/GyanD/codexffmpeg/releases/tag/2021-01-12-git-ca21cb1e36) or [from my first release](https://github.com/AAndyProgram/SCrawler/releases/download/1.0.0.0/ffmpeg.zip)). **ffmpeg only works with the x64 version of the program.**
|
||||
- **Don't put program in the ```Program Files``` system folder (this is portable program and program settings are stored in the program folder)**
|
||||
- **Just unzip the program archive to any folder, copy the file ```ffmpeg.exe``` into it and enjoy. :)**
|
||||
|
||||
@@ -69,6 +76,7 @@ You can add users by patterns:
|
||||
- https://twitter.com/SomeUserName
|
||||
- https://reddit.com/user/SomeUserName
|
||||
- https://reddit.com/r/SomeSubredditName
|
||||
- https://www.redgifs.com/users/SomeUserName
|
||||
- u/SomeUserName
|
||||
- r/SomeSubredditName
|
||||
- SomeUserName (in this case, you need to select the user's site)
|
||||
@@ -83,3 +91,8 @@ Read more about adding users and subreddits [here](https://github.com/AAndyProgr
|
||||
Create a shortcut for the program. Open shortcut properties. In the ```Shortcut``` tab, in the ```Target``` field, just add the letter ```v``` at the end across the space.
|
||||
|
||||
Example: ```D:\Programs\SCrawler\SCrawler.exe v```
|
||||
|
||||
# Contact me
|
||||
|
||||
[Element messenger](https://element.io/): @andyprogram:matrix.org
|
||||
https://matrix.to/#/@andyprogram:matrix.org
|
||||
@@ -11,13 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.gitignore = .gitignore
|
||||
Changelog.md = Changelog.md
|
||||
Info\InstaAlgo.txt = Info\InstaAlgo.txt
|
||||
Info\InstagramInfo.txt = Info\InstagramInfo.txt
|
||||
README.md = README.md
|
||||
Info\RedditUrlsInfo.txt = Info\RedditUrlsInfo.txt
|
||||
ToDo.txt = ToDo.txt
|
||||
Info\TwitterNewAlgo.txt = Info\TwitterNewAlgo.txt
|
||||
Info\TwitterUrlsInfo.txt = Info\TwitterUrlsInfo.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
|
||||
@@ -25,7 +25,9 @@ Namespace API.Base
|
||||
_Path.Value = NewFile
|
||||
End Set
|
||||
End Property
|
||||
#Region "Instagram"
|
||||
Friend ReadOnly Property InstaHash As XMLValue(Of String)
|
||||
Friend ReadOnly Property InstaHash_SP As XMLValue(Of String)
|
||||
Friend ReadOnly Property InstaHashUpdateRequired As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property InstagramDownloadingErrorDate As XMLValue(Of Date)
|
||||
Friend Property InstagramLastApplyingValue As Integer? = Nothing
|
||||
@@ -40,7 +42,18 @@ Namespace API.Base
|
||||
End With
|
||||
End Get
|
||||
End Property
|
||||
Friend Property InstagramTooManyRequestsReadyForCatch As Boolean = True
|
||||
Friend ReadOnly Property InstagramLastDownloadDate As XMLValue(Of Date)
|
||||
Friend ReadOnly Property InstagramLastRequestsCount As XMLValue(Of Integer)
|
||||
Private InstagramTooManyRequestsReadyForCatch As Boolean = True
|
||||
Friend Function GetInstaWaitDate() As Date
|
||||
With InstagramDownloadingErrorDate
|
||||
If .ValueF.Exists Then
|
||||
Return .ValueF.Value.AddMinutes(If(InstagramLastApplyingValue, 10))
|
||||
Else
|
||||
Return Now
|
||||
End If
|
||||
End With
|
||||
End Function
|
||||
Friend Sub InstagramTooManyRequests(ByVal Catched As Boolean)
|
||||
With InstagramDownloadingErrorDate
|
||||
If Catched Then
|
||||
@@ -55,9 +68,14 @@ Namespace API.Base
|
||||
Else
|
||||
.ValueF = Nothing
|
||||
InstagramLastApplyingValue = Nothing
|
||||
InstagramTooManyRequestsReadyForCatch = True
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
Friend ReadOnly Property RequestsWaitTimer As XMLValue(Of Integer)
|
||||
Friend ReadOnly Property RequestsWaitTimerTaskCount As XMLValue(Of Integer)
|
||||
Friend ReadOnly Property SleepTimerOnPostsLimit As XMLValue(Of Integer)
|
||||
#End Region
|
||||
Friend ReadOnly Property Temporary As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property DownloadImages As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property DownloadVideos As XMLValue(Of Boolean)
|
||||
@@ -98,6 +116,7 @@ Namespace API.Base
|
||||
Responser.CookiesDomain = "reddit.com"
|
||||
Responser.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
||||
Case Sites.Instagram : Responser.CookiesDomain = "instagram.com"
|
||||
Case Sites.RedGifs : Responser.CookiesDomain = "redgifs.com"
|
||||
End Select
|
||||
Responser.SaveSettings()
|
||||
End If
|
||||
@@ -126,20 +145,30 @@ Namespace API.Base
|
||||
GetUserMediaOnly = New XMLValue(Of Boolean)
|
||||
End If
|
||||
|
||||
CreateProp(InstaHashUpdateRequired, Sites.Instagram, "InstaHashUpdateRequired", True, _XML, n)
|
||||
CreateProp(InstaHash, Sites.Instagram, "InstaHash", String.Empty, _XML, n)
|
||||
If Site = Sites.Instagram AndAlso (InstaHash.IsEmptyString Or InstaHashUpdateRequired) AndAlso Responser.Cookies.ListExists Then GatherInstaHash()
|
||||
CreateProp(InstaHash_SP, Sites.Instagram, "InstaHashSavedPosts", String.Empty, _XML, n)
|
||||
CreateProp(InstagramLastDownloadDate, Sites.Instagram, "LastDownloadDate", Now.AddDays(-1), _XML, n)
|
||||
CreateProp(InstagramLastRequestsCount, Sites.Instagram, "LastRequestsCount", 0, _XML, n)
|
||||
CreateProp(RequestsWaitTimer, Sites.Instagram, "RequestsWaitTimer", 1000, _XML, n)
|
||||
CreateProp(RequestsWaitTimerTaskCount, Sites.Instagram, "RequestsWaitTimerTaskCount", 1, _XML, n)
|
||||
CreateProp(SleepTimerOnPostsLimit, Sites.Instagram, "SleepTimerOnPostsLimit", 60000, _XML, n)
|
||||
If Site = Sites.Instagram Then
|
||||
InstaHash = New XMLValue(Of String)("InstaHash", String.Empty, _XML, n)
|
||||
InstaHashUpdateRequired = New XMLValue(Of Boolean)("InstaHashUpdateRequired", True, _XML, n)
|
||||
If (InstaHash.IsEmptyString Or InstaHashUpdateRequired) And Responser.Cookies.ListExists Then GatherInstaHash()
|
||||
InstagramDownloadingErrorDate = New XMLValue(Of Date) With {.ToStringFunction = Function(ss, vv) AConvert(Of String)(vv, Nothing)}
|
||||
InstagramDownloadingErrorDate.SetExtended("InstagramDownloadingErrorDate", Now.AddYears(-10), _XML, n)
|
||||
Else
|
||||
InstaHash = New XMLValue(Of String)
|
||||
InstaHashUpdateRequired = New XMLValue(Of Boolean)
|
||||
InstagramDownloadingErrorDate = New XMLValue(Of Date)
|
||||
End If
|
||||
If Site = Sites.Reddit Then
|
||||
SavedPostsUserName = New XMLValue(Of String)("SavedPostsUserName", String.Empty, _XML, n)
|
||||
|
||||
SavedPostsUserName = New XMLValue(Of String)("SavedPostsUserName", String.Empty, _XML, n)
|
||||
End Sub
|
||||
Private Sub CreateProp(Of T)(ByRef p As XMLValue(Of T), ByVal s As Sites,
|
||||
ByVal p_Name As String, ByVal p_Value As T, ByRef x As XmlFile, ByVal n() As String)
|
||||
If Site = s Then
|
||||
p = New XMLValue(Of T)(p_Name, p_Value, x, n)
|
||||
Else
|
||||
SavedPostsUserName = New XMLValue(Of String)
|
||||
p = New XMLValue(Of T)
|
||||
End If
|
||||
End Sub
|
||||
Friend Sub Update()
|
||||
|
||||
@@ -85,5 +85,21 @@ Namespace API.Base
|
||||
Return v
|
||||
End Function
|
||||
End Structure
|
||||
Friend Structure Sizes : Implements IComparable(Of Sizes)
|
||||
Friend Value As Integer
|
||||
Friend Data As String
|
||||
Friend ReadOnly HasError As Boolean
|
||||
Friend Sub New(ByVal _Value As String, ByVal _Data As String)
|
||||
Try
|
||||
Value = _Value
|
||||
Data = _Data
|
||||
Catch ex As Exception
|
||||
HasError = True
|
||||
End Try
|
||||
End Sub
|
||||
Friend Function CompareTo(ByVal Other As Sizes) As Integer Implements IComparable(Of Sizes).CompareTo
|
||||
Return Value.CompareTo(Other.Value) * -1
|
||||
End Function
|
||||
End Structure
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -7,9 +7,12 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports System.IO
|
||||
Imports System.Net
|
||||
Imports System.Threading
|
||||
Imports UState = SCrawler.API.Base.UserMedia.States
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.Base
|
||||
Friend MustInherit Class UserDataBase : Implements IUserData
|
||||
Friend Const UserFileAppender As String = "User"
|
||||
@@ -77,10 +80,17 @@ Namespace API.Base
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
Friend MustOverride Property Site As Sites Implements IContentProvider.Site
|
||||
Protected _Progress As MyProgress
|
||||
Friend Overridable Property Progress As MyProgress
|
||||
Get
|
||||
If _Progress Is Nothing Then Return MainProgress Else Return _Progress
|
||||
End Get
|
||||
Set(ByVal p As MyProgress)
|
||||
_Progress = p
|
||||
End Set
|
||||
End Property
|
||||
Friend User As UserInfo
|
||||
Friend Property IsSavedPosts As Boolean
|
||||
Protected Const NonExistendUserHelp As String = "404"
|
||||
Protected Const SuspendedUserHelp As String = "403"
|
||||
Friend Overridable Property UserExists As Boolean = True Implements IUserData.Exists
|
||||
Friend Overridable Property UserSuspended As Boolean = False Implements IUserData.Suspended
|
||||
Friend Overridable Property Name As String Implements IContentProvider.Name
|
||||
@@ -288,7 +298,7 @@ BlockNullPicture:
|
||||
#End Region
|
||||
#Region "Information"
|
||||
Protected _CountVideo As Integer = 0
|
||||
Protected _CountPictures As Integer = 0
|
||||
Protected Property _CountPictures As Integer = 0
|
||||
Friend Overridable Property LastUpdated As Date?
|
||||
Friend ReadOnly Property TotalContentCount As Integer
|
||||
Get
|
||||
@@ -339,7 +349,7 @@ BlockNullPicture:
|
||||
Friend ReadOnly Property LVIKey As String Implements IUserData.LVIKey
|
||||
Get
|
||||
If Not _IsCollection Then
|
||||
Return $"{Interaction.Switch(Site = Sites.Reddit, "R", Site = Sites.Twitter, "T", Site = Sites.Instagram, "I")}_{Name}"
|
||||
Return $"{Site.ToString.ToUpper.Substring(0, 1)}_{Name}"
|
||||
Else
|
||||
Return $"CCCC_{CollectionName}"
|
||||
End If
|
||||
@@ -436,6 +446,7 @@ BlockNullPicture:
|
||||
End If
|
||||
Case Sites.Twitter : Return New Twitter.UserData(u, _LoadUserInformation)
|
||||
Case Sites.Instagram : Return New Instagram.UserData(u, _LoadUserInformation)
|
||||
Case Sites.RedGifs : Return New RedGifs.UserData(u, _LoadUserInformation)
|
||||
Case Else : Throw New ArgumentOutOfRangeException("Site", $"Site [{u.Site}] information does not recognized by loader")
|
||||
End Select
|
||||
End Function
|
||||
@@ -469,6 +480,7 @@ BlockNullPicture:
|
||||
DataMerging = x.Value(Name_DataMerging).FromXML(Of Boolean)(False)
|
||||
ChangeCollectionName(x.Value(Name_CollectionName), False)
|
||||
Labels.ListAddList(x.Value(Name_LabelsName).StringToList(Of String, List(Of String))("|", EDP.ReturnValue), LAP.NotContainsOnly, LAP.ClearBeforeAdd)
|
||||
LoadUserInformation_OptionalFields(x, True)
|
||||
End Using
|
||||
UpdateDataFiles()
|
||||
End If
|
||||
@@ -506,6 +518,8 @@ BlockNullPicture:
|
||||
x.Add(Name_LabelsName, Labels.ListToString(, "|", EDP.ReturnValue))
|
||||
x.Add(Name_DataMerging, DataMerging.BoolToInteger)
|
||||
|
||||
LoadUserInformation_OptionalFields(x, False)
|
||||
|
||||
x.Save(MyFile)
|
||||
End Using
|
||||
If Not IsSavedPosts Then Settings.UpdateUsersList(User)
|
||||
@@ -513,16 +527,15 @@ BlockNullPicture:
|
||||
LogError(ex, "user information saving error")
|
||||
End Try
|
||||
End Sub
|
||||
''' <param name="Loading"><see langword="True"/>: Loading; <see langword="False"/>: Saving</param>
|
||||
Protected MustOverride Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
#End Region
|
||||
#Region "User data"
|
||||
Friend Overridable Overloads Sub LoadContentInformation()
|
||||
UpdateDataFiles()
|
||||
LoadContentInformation(_ContentList, MyFileData)
|
||||
End Sub
|
||||
Private Overloads Sub LoadContentInformation(ByRef _CLIST As List(Of UserMedia), ByVal f As SFile)
|
||||
Try
|
||||
If Not f.Exists Then Exit Sub
|
||||
Using x As New XmlFile(f, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True}
|
||||
UpdateDataFiles()
|
||||
If Not MyFileData.Exists Then Exit Sub
|
||||
Using x As New XmlFile(MyFileData, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True}
|
||||
x.LoadData()
|
||||
If x.Count > 0 Then
|
||||
Dim fs$ = MyFile.CutPath.PathWithSeparator
|
||||
@@ -538,7 +551,7 @@ BlockNullPicture:
|
||||
End If
|
||||
End Function
|
||||
For Each v As EContainer In x
|
||||
_CLIST.Add(New UserMedia With {
|
||||
_ContentList.Add(New UserMedia With {
|
||||
.Type = AConvert(Of Integer)(v.Attribute(Name_MediaType).Value, 0),
|
||||
.URL = v.Attribute(Name_MediaURL).Value,
|
||||
.URL_BASE = v.Value,
|
||||
@@ -556,14 +569,14 @@ BlockNullPicture:
|
||||
LogError(ex, "history loading error")
|
||||
End Try
|
||||
End Sub
|
||||
Friend Sub UpdateContentInformation(ByRef _CLIST As List(Of UserMedia), ByVal f As SFile)
|
||||
Friend Sub UpdateContentInformation()
|
||||
Try
|
||||
UpdateDataFiles()
|
||||
If f.IsEmptyString Then Exit Sub
|
||||
f.Exists(SFO.Path)
|
||||
If MyFileData.IsEmptyString Then Exit Sub
|
||||
MyFileData.Exists(SFO.Path)
|
||||
Using x As New XmlFile With {.AllowSameNames = True, .Name = "Data"}
|
||||
If _CLIST.Count > 0 Then
|
||||
For Each i As UserMedia In _CLIST
|
||||
If _ContentList.Count > 0 Then
|
||||
For Each i As UserMedia In _ContentList
|
||||
x.Add(New EContainer("MediaData", i.URL_BASE,
|
||||
{New EAttribute(Name_MediaType, CInt(i.Type)),
|
||||
New EAttribute(Name_MediaURL, i.URL),
|
||||
@@ -631,9 +644,9 @@ BlockNullPicture:
|
||||
ThrowAny(Token)
|
||||
|
||||
If _TempMediaList.Count > 0 Then
|
||||
If Not DownloadImages Then _TempMediaList.RemoveAll(Function(m) m.Type = UserMedia.Types.GIF Or m.Type = UserMedia.Types.Picture)
|
||||
If Not DownloadVideos Then _TempMediaList.RemoveAll(Function(m) m.Type = UserMedia.Types.Video Or
|
||||
m.Type = UserMedia.Types.VideoPre Or m.Type = UserMedia.Types.m3u8)
|
||||
If Not DownloadImages Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.GIF Or m.Type = UTypes.Picture)
|
||||
If Not DownloadVideos Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.Video Or
|
||||
m.Type = UTypes.VideoPre Or m.Type = UTypes.m3u8)
|
||||
End If
|
||||
|
||||
ReparseVideo(Token)
|
||||
@@ -642,14 +655,14 @@ BlockNullPicture:
|
||||
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
|
||||
DownloadContent(Token)
|
||||
ThrowIfDisposed()
|
||||
_ContentList.ListAddList(_ContentNew.Where(Function(c) c.State = UState.Downloaded), LNC)
|
||||
_CountPictures = _ContentList.LongCount(Function(c) c.Type = UserMedia.Types.Picture)
|
||||
_CountVideo = _ContentList.LongCount(Function(c) c.Type = UserMedia.Types.Video)
|
||||
_ContentList.ListAddList(_ContentNew.Where(Function(c) c.State = UStates.Downloaded), LNC)
|
||||
_CountPictures = _ContentList.LongCount(Function(c) c.Type = UTypes.Picture)
|
||||
_CountVideo = _ContentList.LongCount(Function(c) c.Type = UTypes.Video)
|
||||
If DownloadedPictures + DownloadedVideos > 0 Or EnvirChanged.Invoke Then
|
||||
If __SaveData Then
|
||||
LastUpdated = Now
|
||||
If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser)
|
||||
UpdateContentInformation(_ContentList, MyFileData)
|
||||
UpdateContentInformation()
|
||||
Else
|
||||
_CountVideo = 0
|
||||
_CountPictures = 0
|
||||
@@ -660,8 +673,10 @@ BlockNullPicture:
|
||||
UpdateUserInformation()
|
||||
End If
|
||||
ThrowIfDisposed()
|
||||
_DownloadedPicturesTotal += _DownloadedPicturesSession
|
||||
_DownloadedVideosTotal += _DownloadedVideosSession
|
||||
If Not CreatedByChannel Then
|
||||
_DownloadedPicturesTotal += _DownloadedPicturesSession
|
||||
_DownloadedVideosTotal += _DownloadedVideosSession
|
||||
End If
|
||||
If UpPic Or EnvirChanged.Invoke Then Raise_OnUserUpdated()
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
MyMainLOG = $"{Site} - {Name}: downloading canceled"
|
||||
@@ -692,6 +707,99 @@ BlockNullPicture:
|
||||
Protected MustOverride Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
Protected MustOverride Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||
Protected MustOverride Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
Protected Sub DownloadContentDefault(ByVal Token As CancellationToken)
|
||||
Try
|
||||
Dim i%
|
||||
Dim dCount% = 0, dTotal% = 0
|
||||
ThrowAny(Token)
|
||||
If _ContentNew.Count > 0 Then
|
||||
_ContentNew.RemoveAll(Function(c) c.URL.IsEmptyString)
|
||||
If _ContentNew.Count > 0 Then
|
||||
MyFile.Exists(SFO.Path)
|
||||
Dim MyDir$ = MyFile.CutPath.PathNoSeparator
|
||||
Dim vsf As Boolean = SeparateVideoFolderF
|
||||
Dim __isVideo As Boolean
|
||||
Dim f As SFile
|
||||
Dim v As UserMedia
|
||||
Using w As New WebClient
|
||||
If vsf Then SFileShares.SFileExists($"{MyDir}\Video\", SFO.Path)
|
||||
Progress.TotalCount += _ContentNew.Count
|
||||
For i = 0 To _ContentNew.Count - 1
|
||||
ThrowAny(Token)
|
||||
v = _ContentNew(i)
|
||||
v.State = UStates.Tried
|
||||
If v.File.IsEmptyString Then
|
||||
f = v.URL
|
||||
Else
|
||||
f = v.File
|
||||
End If
|
||||
f.Separator = "\"
|
||||
f.Path = MyDir
|
||||
|
||||
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
||||
|
||||
If Not v.File.IsEmptyString And Not v.URL_BASE.IsEmptyString Then
|
||||
Try
|
||||
__isVideo = v.Type = UTypes.Video Or f.Extension = "mp4"
|
||||
|
||||
If f.Extension.IsEmptyString Then
|
||||
Select Case v.Type
|
||||
Case UTypes.Picture : f.Extension = "jpg"
|
||||
Case UTypes.Video : f.Extension = "mp4"
|
||||
Case UTypes.GIF : f.Extension = "gif"
|
||||
End Select
|
||||
End If
|
||||
|
||||
If __isVideo And vsf Then f.Path = $"{f.PathWithSeparator}Video"
|
||||
w.DownloadFile(v.URL_BASE, f.ToString)
|
||||
|
||||
If __isVideo Then
|
||||
v.Type = UTypes.Video
|
||||
DownloadedVideos += 1
|
||||
_CountVideo += 1
|
||||
Else
|
||||
v.Type = UTypes.Picture
|
||||
DownloadedPictures += 1
|
||||
_CountPictures += 1
|
||||
End If
|
||||
|
||||
v.File = ChangeFileNameByProvider(f, v)
|
||||
v.State = UStates.Downloaded
|
||||
dCount += 1
|
||||
Catch wex As Exception
|
||||
ErrorDownloading(f, v.URL_BASE)
|
||||
End Try
|
||||
Else
|
||||
v.State = UStates.Skipped
|
||||
End If
|
||||
_ContentNew(i) = v
|
||||
If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then
|
||||
Progress.Perform(_ContentNew.Count - dTotal)
|
||||
Exit Sub
|
||||
Else
|
||||
dTotal += 1
|
||||
Progress.Perform()
|
||||
End If
|
||||
Next
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
LogError(ex, "content downloading error")
|
||||
HasError = True
|
||||
End Try
|
||||
End Sub
|
||||
''' <param name="RDE">Request DownloadingException</param>
|
||||
Protected Sub ProcessException(ByVal ex As Exception, ByVal Token As CancellationToken, ByVal Message As String, Optional ByVal RDE As Boolean = True)
|
||||
If Not ((TypeOf ex Is OperationCanceledException And Token.IsCancellationRequested) Or
|
||||
(TypeOf ex Is ObjectDisposedException And Disposed)) Then
|
||||
If RDE AndAlso DownloadingException(ex, Message, True) = 0 Then LogError(ex, Message) : HasError = True
|
||||
End If
|
||||
End Sub
|
||||
''' <summary>0 - Execute LogError and set HasError</summary>
|
||||
Protected MustOverride Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
|
||||
Protected Function ChangeFileNameByProvider(ByVal f As SFile, ByVal m As UserMedia) As SFile
|
||||
Dim ff As SFile = Nothing
|
||||
Try
|
||||
@@ -1020,7 +1128,7 @@ BlockNullPicture:
|
||||
''' 0 - Nothing removed<br/>
|
||||
''' 1 - User removed<br/>
|
||||
''' 2 - Collection removed<br/>
|
||||
''' 3 - Collection splitted
|
||||
''' 3 - Collection split
|
||||
''' </summary>
|
||||
Function Delete() As Integer
|
||||
Function MoveFiles(ByVal CollectionName As String) As Boolean
|
||||
|
||||
@@ -46,8 +46,7 @@ Namespace API.Imgur
|
||||
End If
|
||||
Return Nothing
|
||||
Catch ex As Exception
|
||||
If Not e.Exists Then e = New ErrorsDescriber(EDP.ReturnValue + EDP.SendInLog)
|
||||
Return ErrorsDescriber.Execute(e, ex, $"[API.Imgur.Envir.GetGallery({URL})]", Nothing)
|
||||
Return DownloadingException(ex, $"[API.Imgur.Envir.GetGallery({URL})]", Nothing, e)
|
||||
End Try
|
||||
End Function
|
||||
Friend Shared Function GetImage(ByVal URL As String, Optional ByVal e As ErrorsDescriber = Nothing) As String
|
||||
@@ -64,8 +63,7 @@ Namespace API.Imgur
|
||||
End If
|
||||
Return String.Empty
|
||||
Catch ex As Exception
|
||||
If Not e.Exists Then e = New ErrorsDescriber(EDP.ReturnValue + EDP.SendInLog)
|
||||
Return ErrorsDescriber.Execute(e, ex, $"[API.Imgur.Envir.GetImage({URL})]", String.Empty)
|
||||
Return DownloadingException(ex, $"[API.Imgur.Envir.GetImage({URL})]", String.Empty, e)
|
||||
End Try
|
||||
End Function
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||
@@ -83,5 +81,21 @@ Namespace API.Imgur
|
||||
Return ErrorsDescriber.Execute(EDP.ShowMainMsg + EDP.SendInLog, ex, "Imgur standalone downloader: fetch media error")
|
||||
End Try
|
||||
End Function
|
||||
Private Shared Function DownloadingException(ByVal ex As Exception, ByVal Message As String,
|
||||
ByVal NullArg As Object, ByVal e As ErrorsDescriber) As Object
|
||||
If TypeOf ex Is WebException Then
|
||||
Dim obj As HttpWebResponse = TryCast(DirectCast(ex, WebException).Response, HttpWebResponse)
|
||||
If Not obj Is Nothing Then
|
||||
If obj.StatusCode = HttpStatusCode.NotFound Then
|
||||
Return NullArg
|
||||
ElseIf obj.StatusCode = HttpStatusCode.Unauthorized Then
|
||||
MyMainLOG = "Imgur credentials expired"
|
||||
Return NullArg
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
If Not e.Exists Then e = New ErrorsDescriber(EDP.ReturnValue + EDP.SendInLog)
|
||||
Return ErrorsDescriber.Execute(e, ex, Message, NullArg)
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -8,7 +8,7 @@
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.Instagram
|
||||
Friend Module Declarations
|
||||
Friend ReadOnly FilesPattern As New RegexStructure("[^\./]+?\.\w+", True, False, 2,,,, String.Empty, EDP.ReturnValue)
|
||||
Friend ReadOnly FilesPattern As New RegexStructure(".+?([^/\?]+?\.[\w\d]{3,4})(?=(\?|\Z))",,,, 1,,, String.Empty, EDP.ReturnValue)
|
||||
Friend ReadOnly Property DateProvider As New JsonDate
|
||||
Friend Class JsonDate : Implements ICustomProvider
|
||||
Friend Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
|
||||
44
SCrawler/API/Instagram/ProfileSaved.vb
Normal file
44
SCrawler/API/Instagram/ProfileSaved.vb
Normal file
@@ -0,0 +1,44 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports System.Threading
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Namespace API.Instagram
|
||||
Friend NotInheritable Class ProfileSaved
|
||||
Friend Shared ReadOnly Property DataPath As SFile = $"{Settings(Sites.Instagram).Path.PathNoSeparator}\!Saved\"
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Friend Shared Sub Download(ByRef Bar As MyProgress, ByVal Token As CancellationToken)
|
||||
Try
|
||||
Dim u As New UserInfo(Settings(Sites.Instagram).SavedPostsUserName.Value, Sites.Instagram) With {.SpecialPath = DataPath}
|
||||
u.UpdateUserFile()
|
||||
Using user As New UserData(u,, False)
|
||||
DirectCast(user.Self, UserDataBase).IsSavedPosts = True
|
||||
user.Progress = Bar
|
||||
If Not user.FileExists Then user.UpdateUserInformation()
|
||||
If Settings(Sites.Instagram).InstagramLastDownloadDate.Value < Now.AddMinutes(60) Then
|
||||
user.RequestsCount = Settings(Sites.Instagram).InstagramLastRequestsCount
|
||||
End If
|
||||
user.DownloadData(Token)
|
||||
Bar.InformationTemporary = $"Images: {user.DownloadedPictures}; Videos: {user.DownloadedVideos}"
|
||||
With Settings
|
||||
.BeginUpdate()
|
||||
With .Site(Sites.Instagram)
|
||||
.InstagramLastDownloadDate.Value = Now
|
||||
.InstagramLastRequestsCount.Value = user.RequestsCount
|
||||
End With
|
||||
.EndUpdate()
|
||||
End With
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[API.Instagram.ProfileSaved.Download]")
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -7,103 +7,275 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.Messaging
|
||||
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API.Base
|
||||
Imports System.Threading
|
||||
Imports System.Net
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.Instagram
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Private Const MaxPostsCount As Integer = 200
|
||||
Private Const Name_LastCursor As String = "LastCursor"
|
||||
Private Const Name_FirstLoadingDone As String = "FirstLoadingDone"
|
||||
Friend Overrides Property Site As Sites = Sites.Instagram
|
||||
Friend Overrides Property Progress As MyProgress
|
||||
Get
|
||||
If Not _Progress Is Nothing Then Return _Progress Else Return MainProgressInst
|
||||
End Get
|
||||
Set(ByVal p As MyProgress)
|
||||
_Progress = p
|
||||
End Set
|
||||
End Property
|
||||
Private ReadOnly _SavedPostsIDs As New List(Of String)
|
||||
Private LastCursor As String = String.Empty
|
||||
Private FirstLoadingDone As Boolean = True
|
||||
''' <summary>Video downloader initializer</summary>
|
||||
Private Sub New()
|
||||
End Sub
|
||||
''' <summary>Default initializer</summary>
|
||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True)
|
||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True, Optional ByVal InvokeImageHandler As Boolean = True)
|
||||
MyBase.New(InvokeImageHandler)
|
||||
User = u
|
||||
If _LoadUserInformation Then LoadUserInformation()
|
||||
End Sub
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
If Loading Then
|
||||
LastCursor = Container.Value(Name_LastCursor)
|
||||
FirstLoadingDone = Container.Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
|
||||
Else
|
||||
Container.Add(Name_LastCursor, LastCursor)
|
||||
Container.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
|
||||
End If
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
DownloadData(String.Empty, Token)
|
||||
Try
|
||||
_InstaHash = String.Empty
|
||||
HasError = False
|
||||
If Not LastCursor.IsEmptyString Then
|
||||
DownloadData(LastCursor, Token)
|
||||
ThrowAny(Token)
|
||||
If Not HasError Then FirstLoadingDone = True
|
||||
End If
|
||||
If Not HasError Then
|
||||
DownloadData(String.Empty, Token)
|
||||
ThrowAny(Token)
|
||||
If Not HasError Then FirstLoadingDone = True
|
||||
End If
|
||||
If FirstLoadingDone Then LastCursor = String.Empty
|
||||
If IsSavedPosts Then DownloadPosts(Token)
|
||||
If WaitNotificationMode = WNM.SkipTemp Or WaitNotificationMode = WNM.SkipCurrent Then WaitNotificationMode = WNM.Notify
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, "[API.Instagram.UserData.DownloadDataF", False)
|
||||
End Try
|
||||
End Sub
|
||||
Private _InstaHash As String = String.Empty
|
||||
#Region "429 bypass"
|
||||
Friend RequestsCount As Integer = 0
|
||||
Friend Enum WNM As Integer
|
||||
Notify = 0
|
||||
SkipCurrent = 1
|
||||
SkipAll = 2
|
||||
SkipTemp = 3
|
||||
End Enum
|
||||
Friend WaitNotificationMode As WNM = WNM.Notify
|
||||
Private Caught429 As Boolean = False
|
||||
Private ProgressTempSet As Boolean = False
|
||||
Private Const InstAborted As String = "InstAborted"
|
||||
Private Function Ready() As Boolean
|
||||
With Settings(Sites.Instagram)
|
||||
If Not .InstagramReadyForDownload Then
|
||||
If WaitNotificationMode = WNM.Notify Then
|
||||
Dim m As New MMessage("Instagram [too many requests] error." & vbCr &
|
||||
$"The program suggests waiting {If(Settings(Sites.Instagram).InstagramLastApplyingValue, 0)} minutes." & vbCr &
|
||||
"What do you want to do?", "Waiting for Instagram download...",
|
||||
{
|
||||
New MsgBoxButton("Wait") With {.ToolTip = "Wait and ask again when the error is found."},
|
||||
New MsgBoxButton("Wait (disable current") With {.ToolTip = "Wait and skip future prompts while downloading the current profile."},
|
||||
New MsgBoxButton("Abort") With {.ToolTip = "Abort operation"},
|
||||
New MsgBoxButton("Wait (disable all)") With {.ToolTip = "Wait and skip future prompts while downloading the current session."}
|
||||
},
|
||||
vbExclamation) With {.ButtonsPerRow = 2, .DefaultButton = 0, .CancelButton = 2}
|
||||
Select Case MsgBoxE(m).Index
|
||||
Case 1 : WaitNotificationMode = WNM.SkipCurrent
|
||||
Case 2 : Throw New OperationCanceledException("Instagram download operation aborted") With {.HelpLink = InstAborted}
|
||||
Case 3 : WaitNotificationMode = WNM.SkipAll
|
||||
Case Else : WaitNotificationMode = WNM.SkipTemp
|
||||
End Select
|
||||
End If
|
||||
If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until {Settings(Sites.Instagram).GetInstaWaitDate().ToString(ParsersDataDateProvider)}"
|
||||
ProgressTempSet = True
|
||||
Return False
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
End With
|
||||
End Function
|
||||
Private Sub ReconfigureAwaiter()
|
||||
If WaitNotificationMode = WNM.SkipTemp Then WaitNotificationMode = WNM.Notify
|
||||
If Caught429 Then Caught429 = False : RequestsCount = 0
|
||||
ProgressTempSet = False
|
||||
End Sub
|
||||
Private Sub NextRequest(ByVal StartWait As Boolean)
|
||||
With Settings(Sites.Instagram)
|
||||
If StartWait And (RequestsCount Mod .RequestsWaitTimerTaskCount.Value) = 0 Then Thread.Sleep(.RequestsWaitTimer)
|
||||
If RequestsCount >= MaxPostsCount - 5 Then Thread.Sleep(.SleepTimerOnPostsLimit)
|
||||
End With
|
||||
End Sub
|
||||
#End Region
|
||||
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Dim _DownloadComplete As Boolean = False
|
||||
LastCursor = Cursor
|
||||
Try
|
||||
Dim n As EContainer, nn As EContainer, node As EContainer
|
||||
Dim HasNextPage As Boolean = False
|
||||
Dim EndCursor$ = String.Empty
|
||||
Dim PostID$ = String.Empty, PostDate$ = String.Empty
|
||||
Do While Not _DownloadComplete
|
||||
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
||||
ReconfigureAwaiter()
|
||||
|
||||
'Check environment
|
||||
If Cursor.IsEmptyString And _InstaHash.IsEmptyString Then _InstaHash = Settings(Sites.Instagram).InstaHash
|
||||
If _InstaHash.IsEmptyString Then Throw New ArgumentNullException("InstHash", "Query hash is null")
|
||||
If ID.IsEmptyString Then GetUserId()
|
||||
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
|
||||
Try
|
||||
Dim n As EContainer, nn As EContainer, node As EContainer
|
||||
Dim HasNextPage As Boolean = False
|
||||
Dim EndCursor$ = String.Empty
|
||||
Dim PostID$ = String.Empty, PostDate$ = String.Empty
|
||||
|
||||
'Create query
|
||||
Dim vars$ = "{""id"":" & ID & ",""first"":12,""after"":""" & Cursor & """}"
|
||||
vars = SymbolsConverter.ASCII.EncodeSymbolsOnly(vars)
|
||||
URL = $"https://www.instagram.com/graphql/query/?query_hash={_InstaHash}&variables={vars}"
|
||||
NextRequest(True)
|
||||
|
||||
'Get response
|
||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
Settings(Sites.Instagram).InstagramTooManyRequests(False)
|
||||
ThrowAny(Token)
|
||||
'Check environment
|
||||
If Cursor.IsEmptyString And _InstaHash.IsEmptyString Then _
|
||||
_InstaHash = If(IsSavedPosts, Settings(Sites.Instagram).InstaHash_SP, Settings(Sites.Instagram).InstaHash).Value
|
||||
If _InstaHash.IsEmptyString Then Throw New ArgumentNullException(IIf(IsSavedPosts, "InstaHashSavedPosts", "InstaHash"), "Query hash is null")
|
||||
If ID.IsEmptyString Then GetUserId()
|
||||
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
|
||||
|
||||
'Data
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
n = j.ItemF({"data", "user", 0}).XmlIfNothing
|
||||
If n.Count > 0 Then
|
||||
If n.Contains("page_info") Then
|
||||
With n("page_info")
|
||||
HasNextPage = .Value("has_next_page").FromXML(Of Boolean)(False)
|
||||
EndCursor = .Value("end_cursor")
|
||||
End With
|
||||
End If
|
||||
n = n("edges").XmlIfNothing
|
||||
If n.Count > 0 Then
|
||||
For Each nn In n
|
||||
ThrowAny(Token)
|
||||
node = nn(0).XmlIfNothing
|
||||
'Create query
|
||||
Dim vars$ = "{""id"":" & ID & ",""first"":50,""after"":""" & Cursor & """}"
|
||||
vars = SymbolsConverter.ASCII.EncodeSymbolsOnly(vars)
|
||||
URL = $"https://www.instagram.com/graphql/query/?query_hash={_InstaHash}&variables={vars}"
|
||||
|
||||
PostID = node.Value("id")
|
||||
If Not PostID.IsEmptyString And _TempPostsList.Contains(PostID) Then Exit Sub
|
||||
_TempPostsList.Add(PostID)
|
||||
PostDate = node.Value("taken_at_timestamp")
|
||||
'Get response
|
||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
Settings(Sites.Instagram).InstagramTooManyRequests(False)
|
||||
RequestsCount += 1
|
||||
ThrowAny(Token)
|
||||
|
||||
ObtainMedia(node, PostID, PostDate)
|
||||
Next
|
||||
End If
|
||||
'Data
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
n = j.ItemF({"data", "user", 0}).XmlIfNothing
|
||||
If n.Count > 0 Then
|
||||
If n.Contains("page_info") Then
|
||||
With n("page_info")
|
||||
HasNextPage = .Value("has_next_page").FromXML(Of Boolean)(False)
|
||||
EndCursor = .Value("end_cursor")
|
||||
End With
|
||||
End If
|
||||
n = n("edges").XmlIfNothing
|
||||
If n.Count > 0 Then
|
||||
For Each nn In n
|
||||
ThrowAny(Token)
|
||||
node = nn(0).XmlIfNothing
|
||||
If IsSavedPosts Then
|
||||
PostID = node.Value("shortcode")
|
||||
If Not PostID.IsEmptyString Then
|
||||
If _TempPostsList.Contains(PostID) Then Exit Sub Else _SavedPostsIDs.Add(PostID)
|
||||
End If
|
||||
Else
|
||||
PostID = node.Value("id")
|
||||
If Not PostID.IsEmptyString And _TempPostsList.Contains(PostID) Then Exit Sub
|
||||
_TempPostsList.Add(PostID)
|
||||
PostDate = node.Value("taken_at_timestamp")
|
||||
ObtainMedia(node, PostID, PostDate)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
Else
|
||||
If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso _TempMediaList.Count = 0 Then
|
||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
||||
UserExists = False
|
||||
_DownloadComplete = True
|
||||
Exit Sub
|
||||
End If
|
||||
End If
|
||||
End Using
|
||||
Else
|
||||
If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso _TempMediaList.Count = 0 Then
|
||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
||||
UserExists = False
|
||||
Exit Sub
|
||||
End If
|
||||
_DownloadComplete = True
|
||||
Exit Sub
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
If HasNextPage And Not EndCursor.IsEmptyString Then DownloadData(EndCursor, Token)
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
MyMainLOG = "Instagram credentials have expired"
|
||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
||||
ElseIf Responser.StatusCode = 429 Then
|
||||
Settings(Sites.Instagram).InstagramTooManyRequests(True)
|
||||
Else
|
||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
||||
LogError(ex, $"data downloading error [{URL}]")
|
||||
End If
|
||||
HasError = True
|
||||
Finally
|
||||
_InstaHash = String.Empty
|
||||
_DownloadComplete = True
|
||||
If HasNextPage And Not EndCursor.IsEmptyString Then DownloadData(EndCursor, Token)
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Exit Do
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Exit Do
|
||||
Catch ex As Exception
|
||||
If DownloadingException(ex, $"data downloading error [{URL}]") = 1 Then Continue Do Else Exit Do
|
||||
End Try
|
||||
Loop
|
||||
Catch oex2 As OperationCanceledException When Token.IsCancellationRequested Or oex2.HelpLink = InstAborted
|
||||
If oex2.HelpLink = InstAborted Then HasError = True
|
||||
Catch DoEx As Exception
|
||||
ProcessException(DoEx, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub DownloadPosts(ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Dim _DownloadComplete As Boolean = False
|
||||
Dim _Index% = 0
|
||||
Try
|
||||
Do While Not _DownloadComplete
|
||||
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
||||
ReconfigureAwaiter()
|
||||
|
||||
Try
|
||||
Dim r$
|
||||
Dim j As EContainer, jj As EContainer
|
||||
Dim _MediaObtained As Boolean
|
||||
If _SavedPostsIDs.Count > 0 And _Index <= _SavedPostsIDs.Count - 1 Then
|
||||
Dim e As New ErrorsDescriber(EDP.ThrowException)
|
||||
For i% = _Index To _SavedPostsIDs.Count - 1
|
||||
_Index = i
|
||||
URL = $"https://instagram.com/p/{_SavedPostsIDs(i)}/?__a=1"
|
||||
ThrowAny(Token)
|
||||
NextRequest((i + 1 Mod 5) = 0)
|
||||
ThrowAny(Token)
|
||||
r = Responser.GetResponse(URL,, e)
|
||||
Settings(Sites.Instagram).InstagramTooManyRequests(False)
|
||||
RequestsCount += 1
|
||||
If Not r.IsEmptyString Then
|
||||
j = JsonDocument.Parse(r)
|
||||
If Not j Is Nothing Then
|
||||
_MediaObtained = False
|
||||
If j.Contains({"graphql", "shortcode_media"}) Then
|
||||
With j({"graphql", "shortcode_media"}).XmlIfNothing
|
||||
If .Count > 0 Then ObtainMedia(.Self, _SavedPostsIDs(i), String.Empty) : _MediaObtained = True
|
||||
End With
|
||||
End If
|
||||
If Not _MediaObtained AndAlso j.Contains("items") Then
|
||||
With j("items")
|
||||
If .Count > 0 Then
|
||||
For Each jj In .Self : ObtainMedia2(jj, _SavedPostsIDs(i)) : Next
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
j.Dispose()
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
_DownloadComplete = True
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Exit Do
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Exit Do
|
||||
Catch ex As Exception
|
||||
If DownloadingException(ex, $"downloading saved posts error [{URL}]") = 1 Then Continue Do Else Exit Do
|
||||
End Try
|
||||
Loop
|
||||
Catch oex2 As OperationCanceledException When Token.IsCancellationRequested Or oex2.HelpLink = InstAborted
|
||||
If oex2.HelpLink = InstAborted Then HasError = True
|
||||
Catch DoEx As Exception
|
||||
ProcessException(DoEx, Token, $"downloading saved posts error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub ObtainMedia(ByVal node As EContainer, ByVal PostID As String, ByVal PostDate As String)
|
||||
@@ -124,6 +296,66 @@ Namespace API.Instagram
|
||||
CreateMedia(node)
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ObtainMedia2(ByVal n As EContainer, ByVal PostID As String)
|
||||
Try
|
||||
Dim img As Predicate(Of EContainer) = Function(_img) Not _img.Name.IsEmptyString AndAlso _img.Name.StartsWith("image_versions") AndAlso _img.Count > 0
|
||||
Dim vid As Predicate(Of EContainer) = Function(_vid) Not _vid.Name.IsEmptyString AndAlso _vid.Name.StartsWith("video_versions") AndAlso _vid.Count > 0
|
||||
Dim ss As Func(Of EContainer, Sizes) = Function(_ss) New Sizes(_ss.Value("width"), _ss.Value("url"))
|
||||
If n.Count > 0 Then
|
||||
Dim l As New List(Of Sizes)
|
||||
Dim d As EContainer
|
||||
Dim t%
|
||||
'8 - gallery
|
||||
'2 - one video
|
||||
'1 - one picture
|
||||
t = n.Value("media_type").FromXML(Of Integer)(-1)
|
||||
If t >= 0 Then
|
||||
Select Case t
|
||||
Case 1
|
||||
If n.Contains(img) Then
|
||||
t = n.Value("media_type").FromXML(Of Integer)(-1)
|
||||
If t >= 0 Then
|
||||
With n.ItemF({img, "candidates"}).XmlIfNothing
|
||||
If .Count > 0 Then
|
||||
l.Clear()
|
||||
l.ListAddList(.Select(ss), LNC)
|
||||
If l.Count > 0 Then
|
||||
l.Sort()
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, Nothing), LNC)
|
||||
l.Clear()
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End If
|
||||
Case 2
|
||||
If n.Contains(vid) Then
|
||||
With n.ItemF({vid}).XmlIfNothing
|
||||
If .Count > 0 Then
|
||||
l.Clear()
|
||||
l.ListAddList(.Select(ss), LNC)
|
||||
If l.Count > 0 Then
|
||||
l.Sort()
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, Nothing), LNC)
|
||||
l.Clear()
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
Case 8
|
||||
With n("carousel_media").XmlIfNothing
|
||||
If .Count > 0 Then
|
||||
For Each d In .Self : ObtainMedia2(d, PostID) : Next
|
||||
End If
|
||||
End With
|
||||
End Select
|
||||
End If
|
||||
l.Clear()
|
||||
End If
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "API.Instagram.GetGallery")
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub GetUserId()
|
||||
Try
|
||||
Dim r$ = Responser.GetResponse($"https://www.instagram.com/{Name}/?__a=1",, EDP.ThrowException)
|
||||
@@ -136,106 +368,71 @@ Namespace API.Instagram
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
Throw ex
|
||||
Else
|
||||
LogError(ex, "get instagram user id")
|
||||
LogError(ex, "get Instagram user id")
|
||||
End If
|
||||
End Try
|
||||
End Sub
|
||||
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
Try
|
||||
Dim i%
|
||||
Dim dCount% = 0, dTotal% = 0
|
||||
ThrowAny(Token)
|
||||
If _ContentNew.Count > 0 Then
|
||||
_ContentNew.RemoveAll(Function(c) c.URL.IsEmptyString)
|
||||
If _ContentNew.Count > 0 Then
|
||||
MyFile.Exists(SFO.Path)
|
||||
Dim MyDir$ = MyFile.CutPath.PathNoSeparator
|
||||
Dim vsf As Boolean = SeparateVideoFolderF
|
||||
Dim f As SFile
|
||||
Dim v As UserMedia
|
||||
Using w As New WebClient
|
||||
If vsf Then SFileShares.SFileExists($"{MyDir}\Video\", SFO.Path)
|
||||
MainProgress.TotalCount += _ContentNew.Count
|
||||
For i = 0 To _ContentNew.Count - 1
|
||||
ThrowAny(Token)
|
||||
v = _ContentNew(i)
|
||||
v.State = UStates.Tried
|
||||
If v.File.IsEmptyString Then
|
||||
f = v.URL
|
||||
Else
|
||||
f = v.File
|
||||
End If
|
||||
f.Separator = "\"
|
||||
f.Path = MyDir
|
||||
|
||||
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
||||
|
||||
If Not v.File.IsEmptyString AndAlso Not v.URL_BASE.IsEmptyString Then
|
||||
Try
|
||||
If v.Type = UTypes.Video And vsf Then f.Path = $"{f.PathWithSeparator}Video"
|
||||
w.DownloadFile(v.URL_BASE, f.ToString)
|
||||
Select Case v.Type
|
||||
Case UTypes.Video : DownloadedVideos += 1 : _CountVideo += 1
|
||||
Case UTypes.Picture : DownloadedPictures += 1 : _CountPictures += 1
|
||||
End Select
|
||||
v.File = ChangeFileNameByProvider(f, v)
|
||||
v.State = UStates.Downloaded
|
||||
Catch wex As Exception
|
||||
ErrorDownloading(f, v.URL_BASE)
|
||||
End Try
|
||||
Else
|
||||
v.State = UStates.Skipped
|
||||
End If
|
||||
_ContentNew(i) = v
|
||||
If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then
|
||||
MainProgress.Perform(_ContentNew.Count - dTotal)
|
||||
Exit Sub
|
||||
Else
|
||||
dTotal += 1
|
||||
MainProgress.Perform()
|
||||
End If
|
||||
Next
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
LogError(ex, "content downloading error")
|
||||
HasError = True
|
||||
End Try
|
||||
DownloadContentDefault(Token)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' <inheritdoc cref="UserDataBase.DownloadingException(Exception, String)"/><br/>
|
||||
''' 1 - continue
|
||||
''' </summary>
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
HasError = True
|
||||
MyMainLOG = "Instagram credentials have expired"
|
||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
||||
ElseIf Responser.StatusCode = 429 Then
|
||||
With Settings(Sites.Instagram)
|
||||
Dim WaiterExists As Boolean = .InstagramLastApplyingValue.HasValue
|
||||
.InstagramTooManyRequests(True)
|
||||
If Not WaiterExists Then .InstagramLastApplyingValue = 2
|
||||
End With
|
||||
Caught429 = True
|
||||
MyMainLOG = $"Number of requests before error 429: {RequestsCount}"
|
||||
Return 1
|
||||
Else
|
||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||
Return 0
|
||||
End If
|
||||
Return 2
|
||||
End Function
|
||||
Private Shared Function MediaFromData(ByVal t As UTypes, ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String) As UserMedia
|
||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID}}
|
||||
If Not m.URL.IsEmptyString Then m.File = CStr(RegexReplace(m.URL, FilesPattern))
|
||||
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, Declarations.DateProvider, Nothing) Else m.Post.Date = Nothing
|
||||
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateProvider, Nothing) Else m.Post.Date = Nothing
|
||||
Return m
|
||||
End Function
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||
Try
|
||||
If Not URL.IsEmptyString AndAlso URL.Contains("instagram.com") Then
|
||||
Do While Right(URL, 1) = "/" : URL = Left(URL, URL.Length - 1) : Loop
|
||||
URL = $"{URL}/?__a=1"
|
||||
Using t As New UserData
|
||||
t.Responser = New PersonalUtilities.Tools.WEB.Response
|
||||
t.Responser.Copy(Settings(Sites.Instagram).Responser)
|
||||
Dim r$ = t.Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
Dim node As EContainer = j({"graphql", "shortcode_media"}).XmlIfNothing
|
||||
If node.Count > 0 Then t.ObtainMedia(node, String.Empty, String.Empty)
|
||||
End Using
|
||||
End If
|
||||
If t._TempMediaList.Count > 0 Then Return ListAddList(Nothing, t._TempMediaList)
|
||||
End Using
|
||||
Dim PID$ = RegexReplace(URL, New RegexStructure(".*?instagram.com/p/([_\w\d]+)", 1))
|
||||
If Not PID.IsEmptyString Then
|
||||
Using t As New UserData
|
||||
t.Responser = New PersonalUtilities.Tools.WEB.Response
|
||||
t.Responser.Copy(Settings(Sites.Instagram).Responser)
|
||||
t._SavedPostsIDs.Add(PID)
|
||||
t.DownloadPosts(Nothing)
|
||||
Return ListAddList(Nothing, t._TempMediaList)
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
Return Nothing
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.ShowMainMsg + EDP.SendInLog, ex, "Instagram standalone downloader: fetch media error")
|
||||
End Try
|
||||
End Function
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If Not disposedValue And disposing Then _SavedPostsIDs.Clear()
|
||||
MyBase.Dispose(disposing)
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -19,6 +19,8 @@ Namespace API.Reddit
|
||||
Private Const Name_ID As String = "ID"
|
||||
Private Const Name_Date As String = "Date"
|
||||
Private Const Name_PostsNode As String = "Posts"
|
||||
Private Const Name_UsersAdded As String = "UsersAdded"
|
||||
Private Const Name_PostsDownloaded As String = "PostsDownloaded"
|
||||
#End Region
|
||||
Friend Const DefaultDownloadLimitCount As Integer = 1000
|
||||
#Region "IUserData Support"
|
||||
@@ -311,6 +313,31 @@ Namespace API.Reddit
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly Property Range As RangeSwitcher(Of UserPost)
|
||||
Friend ReadOnly Property CountOfAddedUsers As List(Of Integer)
|
||||
Friend ReadOnly Property CountOfLoadedPostsPerSession As List(Of Integer)
|
||||
Private _FirstUserAdded As Boolean = False
|
||||
Friend Sub UserAdded(Optional ByVal IsAdded As Boolean = True)
|
||||
If Not _FirstUserAdded Then CountOfAddedUsers.Add(0) : _FirstUserAdded = True
|
||||
Dim v% = CountOfAddedUsers.Last
|
||||
v += IIf(IsAdded, 1, -1)
|
||||
If v < 0 Then v = 0
|
||||
CountOfAddedUsers(CountOfAddedUsers.Count - 1) = v
|
||||
End Sub
|
||||
Friend Function GetChannelStats(ByVal Extended As Boolean) As String
|
||||
Dim s$ = String.Empty
|
||||
Dim p As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||
If Extended Then
|
||||
s.StringAppendLine($"Users added from this channel: {CountOfAddedUsers.Sum.NumToString(p)}")
|
||||
s.StringAppendLine($"Users added from this channel (avg): {CountOfAddedUsers.DefaultIfEmpty(0).Average.RoundDown.NumToString(p)}")
|
||||
s.StringAppendLine($"Users added from this channel (session): {CountOfAddedUsers.LastOrDefault.NumToString(p)}")
|
||||
s.StringAppendLine($"Posts downloaded (avg): {CountOfLoadedPostsPerSession.DefaultIfEmpty(0).Average.RoundUp.NumToString(p)}")
|
||||
s.StringAppendLine($"Posts downloaded (session): {CountOfLoadedPostsPerSession.LastOrDefault.NumToString(p)}")
|
||||
Else
|
||||
s.StringAppend($"Users: {CountOfAddedUsers.Sum.NumToString(p)} (avg: {CountOfAddedUsers.DefaultIfEmpty(0).Average.RoundDown.NumToString(p)}; s: {CountOfAddedUsers.LastOrDefault.NumToString(p)})")
|
||||
s.StringAppend($"Posts: {CountOfLoadedPostsPerSession.DefaultIfEmpty(0).Average.RoundUp.NumToString(p)} (s: {CountOfLoadedPostsPerSession.LastOrDefault.NumToString(p)})", "; ")
|
||||
End If
|
||||
Return s
|
||||
End Function
|
||||
#Region "Limits Support"
|
||||
Private _DownloadLimitCount As Integer? = Nothing
|
||||
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
||||
@@ -379,6 +406,8 @@ Namespace API.Reddit
|
||||
Posts = New List(Of UserPost)
|
||||
PostsLatest = New List(Of UserPost)
|
||||
Range = New RangeSwitcher(Of UserPost)(Me)
|
||||
CountOfAddedUsers = New List(Of Integer)
|
||||
CountOfLoadedPostsPerSession = New List(Of Integer)
|
||||
End Sub
|
||||
Friend Sub New(ByVal f As SFile)
|
||||
Me.New
|
||||
@@ -422,7 +451,9 @@ Namespace API.Reddit
|
||||
}
|
||||
d.SetLimit(Me)
|
||||
d.DownloadData(Token)
|
||||
Dim b% = Posts.Count
|
||||
Posts.ListAddList(d.GetNewChannelPosts(), LAP.NotContainsOnly)
|
||||
If Posts.Count - b > 0 Then CountOfLoadedPostsPerSession.Add(Posts.Count - b)
|
||||
Posts.Sort()
|
||||
LatestParsedDate = If(Posts.FirstOrDefault(Function(pp) pp.Date.HasValue).Date, LatestParsedDate)
|
||||
End Using
|
||||
@@ -525,6 +556,8 @@ Namespace API.Reddit
|
||||
Name = x.Value(Name_Name)
|
||||
ID = x.Value(Name_ID)
|
||||
LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), XMLDateProvider, Nothing)
|
||||
CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), LAP.ClearBeforeAdd)
|
||||
CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), LAP.ClearBeforeAdd)
|
||||
If Not PartialLoad Then
|
||||
With x(Name_PostsNode).XmlIfNothing
|
||||
If .Count > 0 Then .ForEach(Sub(ee) PostsLatest.Add(New UserPost With {
|
||||
@@ -549,6 +582,8 @@ Namespace API.Reddit
|
||||
LatestParsedDate = tmpPostList.FirstOrDefault(Function(pd) pd.Date.HasValue).Date
|
||||
x.Add(Name_Date, AConvert(Of String)(LatestParsedDate, XMLDateProvider, String.Empty))
|
||||
x.Add(Name_PostsNode, String.Empty)
|
||||
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString(, "|"))
|
||||
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString(, "|"))
|
||||
With x(Name_PostsNode)
|
||||
tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post",
|
||||
String.Empty,
|
||||
@@ -578,6 +613,8 @@ Namespace API.Reddit
|
||||
If disposing Then
|
||||
Posts.Clear()
|
||||
PostsLatest.Clear()
|
||||
CountOfAddedUsers.Clear()
|
||||
CountOfLoadedPostsPerSession.Clear()
|
||||
Range.Dispose()
|
||||
If Not Instance Is Nothing Then Instance.Dispose()
|
||||
If CachePath.Exists(SFO.Path, False) Then CachePath.Delete(SFO.Path, False, False, EDP.SendInLog)
|
||||
|
||||
@@ -74,7 +74,6 @@ Namespace API.Reddit
|
||||
Next
|
||||
End If
|
||||
Throw New ArgumentException($"Channel ID [{ChannelID}] does not found in channels collection", "ChannelID") With {.HelpLink = 1}
|
||||
'Return Nothing
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub DownloadData(ByVal Token As CancellationToken, Optional ByVal SkipExists As Boolean = True,
|
||||
@@ -111,7 +110,7 @@ Namespace API.Reddit
|
||||
Return Count > 0 AndAlso Channels.Contains(_Item)
|
||||
End Function
|
||||
Friend Function Remove(ByVal _Item As Channel) As Boolean Implements ICollection(Of Channel).Remove
|
||||
If Count > 0 Then
|
||||
If Count > 0 And Not _Item Is Nothing Then
|
||||
Dim i% = Channels.IndexOf(_Item)
|
||||
If i >= 0 Then
|
||||
With Channels(i) : .Delete() : .Dispose() : End With
|
||||
|
||||
@@ -16,9 +16,8 @@ Namespace API.Reddit
|
||||
Friend ReadOnly VideoRegEx As New RegexStructure("http.{0,1}://[^" & Chr(34) & "]+?mp4", True, False)
|
||||
Friend ReadOnly DateProvider As New JsonDate
|
||||
Friend ReadOnly DateProviderChannel As New JsonDateChannel
|
||||
Private ReadOnly EUR_PROVIDER As New ANumbers(ANumbers.Modes.EUR)
|
||||
Private ReadOnly EUR_PROVIDER As New ANumbers(ANumbers.Cultures.EUR)
|
||||
Friend Class JsonDate : Implements ICustomProvider
|
||||
''' <inheritdoc cref="ADateTime.ParseUnicodeJS(Object, Object, ErrorsDescriber)"/>
|
||||
Friend Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||
Return ADateTime.ParseUnicodeJS(Value, NothingArg, e)
|
||||
@@ -28,7 +27,6 @@ Namespace API.Reddit
|
||||
End Function
|
||||
End Class
|
||||
Friend Class JsonDateChannel : Implements ICustomProvider
|
||||
''' <inheritdoc cref="ADateTime.ParseUnicodeJS(Object, Object, ErrorsDescriber)"/>
|
||||
Friend Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||
Return ADateTime.ParseUnicode(AConvert(Of Integer)(Value, EUR_PROVIDER, Value), NothingArg, e)
|
||||
|
||||
@@ -74,7 +74,7 @@ Namespace API.Reddit
|
||||
ConcatFile.Extension = "mp4"
|
||||
CachePath = $"{f.PathWithSeparator}_Cache\{SFile.GetDirectories($"{f.PathWithSeparator}_Cache\",,, EDP.ReturnValue).ListIfNothing.Count + 1}\"
|
||||
If CachePath.Exists(SFO.Path) Then
|
||||
Dim p As New SFileNumbers(ConcatFile.Name,,, New ANumbers(ANumbers.Modes.USA) With {.GroupSeparator = String.Empty, .FormatMode = ANumbers.Formats.General})
|
||||
Dim p As New SFileNumbers(ConcatFile.Name,,, New ANumbers With {.Format = ANumbers.Formats.General})
|
||||
ConcatFile = SFile.Indexed_IndexFile(ConcatFile,, p, EDP.ReturnValue)
|
||||
Dim i%
|
||||
Dim eFiles As New List(Of SFile)
|
||||
|
||||
@@ -7,29 +7,23 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports System.Threading
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Namespace API.Reddit
|
||||
Friend NotInheritable Class ProfileSaved
|
||||
Friend Shared ReadOnly Property DataPath As SFile = $"{Settings(Sites.Reddit).Path.PathNoSeparator}\!Saved\"
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Friend Shared Sub Download(ByRef Toolbar As StatusStrip, ByRef PR As ToolStripProgressBar)
|
||||
Friend Shared Sub Download(ByRef Bar As MyProgress, ByVal Token As CancellationToken)
|
||||
Try
|
||||
Dim Bar = New PersonalUtilities.Forms.Toolbars.MyProgress(Toolbar, PR, Nothing)
|
||||
Dim u As New UserInfo(Settings(Sites.Reddit).SavedPostsUserName.Value, Sites.Reddit) With {
|
||||
.IsChannel = True,
|
||||
.SpecialPath = $"{Settings(Sites.Reddit).Path.PathWithSeparator}\!Saved\"
|
||||
}
|
||||
Dim u As New UserInfo(Settings(Sites.Reddit).SavedPostsUserName.Value, Sites.Reddit) With {.IsChannel = True, .SpecialPath = DataPath}
|
||||
u.UpdateUserFile()
|
||||
Using user As IUserData = UserDataBase.GetInstance(u)
|
||||
Using user As New UserData(u,, False)
|
||||
DirectCast(user.Self, UserDataBase).IsSavedPosts = True
|
||||
Bar.Enabled = True
|
||||
DirectCast(user.Self, UserData).Progress = Bar
|
||||
user.Progress = Bar
|
||||
If Not user.FileExists Then user.UpdateUserInformation()
|
||||
user.DownloadData(Nothing)
|
||||
Dim m As New MMessage("Reddit saved posts download complete", "Saved posts downloading", {"OK", "Open folder"})
|
||||
m.Text.StringAppendLine($"Downloaded images: {user.DownloadedPictures}")
|
||||
m.Text.StringAppendLine($"Downloaded videos: {user.DownloadedVideos}")
|
||||
If MsgBoxE(m) = 1 Then u.File.CutPath.Open(SFO.Path)
|
||||
Bar.Enabled = False
|
||||
user.DownloadData(Token)
|
||||
Bar.InformationTemporary = $"Images: {user.DownloadedPictures}; Videos: {user.DownloadedVideos}"
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[API.Reddit.ProfileSaved.Download]")
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports PersonalUtilities.Tools.ImageRenderer
|
||||
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
||||
Imports System.Net
|
||||
@@ -50,15 +49,6 @@ Namespace API.Reddit
|
||||
Select c.Post) Else Return Nothing
|
||||
End Function
|
||||
#End Region
|
||||
Private _Progress As MyProgress
|
||||
Friend Property Progress As MyProgress
|
||||
Get
|
||||
If _Progress Is Nothing Then Return MainProgress Else Return _Progress
|
||||
End Get
|
||||
Set(ByVal p As MyProgress)
|
||||
_Progress = p
|
||||
End Set
|
||||
End Property
|
||||
#Region "Initializers"
|
||||
''' <summary>Video downloader initializer</summary>
|
||||
Private Sub New()
|
||||
@@ -74,9 +64,13 @@ Namespace API.Reddit
|
||||
If _LoadUserInformation Then LoadUserInformation()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Load and Update user info"
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download Overrides"
|
||||
Friend Overrides Sub DownloadData(ByVal Token As CancellationToken)
|
||||
If IsChannel AndAlso Not ChannelInfo.IsRegularChannel Then
|
||||
If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo.IsRegularChannel) Then
|
||||
If Not Responser Is Nothing Then Responser.Dispose()
|
||||
Responser = New PersonalUtilities.Tools.WEB.Response
|
||||
Responser.Copy(Settings(Sites.Reddit).Responser)
|
||||
@@ -92,7 +86,9 @@ Namespace API.Reddit
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
_TotalPostsDownloaded = 0
|
||||
If IsChannel Then
|
||||
If IsSavedPosts Then
|
||||
DownloadDataChannel(String.Empty, Token)
|
||||
ElseIf IsChannel Then
|
||||
If ChannelInfo.IsRegularChannel Then
|
||||
ChannelPostsNames.ListAddList(_TempPostsList, LNC)
|
||||
If ChannelPostsNames.Count > 0 Then
|
||||
@@ -129,7 +125,7 @@ Namespace API.Reddit
|
||||
|
||||
URL = $"https://gateway.reddit.com/desktopapi/v1/user/{Name}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort=new&t=all&layout=classic"
|
||||
ThrowAny(Token)
|
||||
Dim r$ = GetSiteResponse(URL)
|
||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
If Not r.IsEmptyString Then
|
||||
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
If w.Count > 0 Then
|
||||
@@ -203,17 +199,8 @@ Namespace API.Reddit
|
||||
If POST.IsEmptyString And ExistsDetected Then Exit Sub
|
||||
If Not PostID.IsEmptyString And NewPostDetected Then DownloadDataUser(PostID, Token)
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
If ex.HelpLink = NonExistendUserHelp Then
|
||||
UserExists = False
|
||||
ElseIf ex.HelpLink = SuspendedUserHelp Then
|
||||
UserSuspended = True
|
||||
Else
|
||||
LogError(ex, $"data downloading error [{URL}]")
|
||||
HasError = True
|
||||
End If
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub DownloadDataChannel(ByVal POST As String, ByVal Token As CancellationToken)
|
||||
@@ -234,7 +221,7 @@ Namespace API.Reddit
|
||||
End If
|
||||
|
||||
ThrowAny(Token)
|
||||
Dim r$ = GetSiteResponse(URL)
|
||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
If Not r.IsEmptyString Then
|
||||
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
If w.Count > 0 Then
|
||||
@@ -296,17 +283,8 @@ Namespace API.Reddit
|
||||
If POST.IsEmptyString And ExistsDetected Then Exit Sub
|
||||
If Not PostID.IsEmptyString And NewPostDetected Then DownloadDataChannel(PostID, Token)
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
If ex.HelpLink = NonExistendUserHelp Then
|
||||
UserExists = False
|
||||
ElseIf ex.HelpLink = SuspendedUserHelp Then
|
||||
UserSuspended = True
|
||||
Else
|
||||
LogError(ex, $"channel data downloading error [{URL}]")
|
||||
HasError = True
|
||||
End If
|
||||
ProcessException(ex, Token, $"channel data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
#End Region
|
||||
@@ -366,8 +344,7 @@ Namespace API.Reddit
|
||||
End If
|
||||
Return added
|
||||
Catch ex As Exception
|
||||
LogError(ex, "gallery parsing error")
|
||||
HasError = True
|
||||
ProcessException(ex, Nothing, "gallery parsing error", False)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
@@ -382,7 +359,7 @@ Namespace API.Reddit
|
||||
ThrowAny(Token)
|
||||
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
||||
m = _TempMediaList(i)
|
||||
r = GetSiteResponse(m.URL, e)
|
||||
r = Responser.GetResponse(m.URL,, e)
|
||||
_TempMediaList(i) = New UserMedia
|
||||
If Not r.IsEmptyString Then
|
||||
v = RegexReplace(r, VideoRegEx)
|
||||
@@ -395,10 +372,8 @@ Namespace API.Reddit
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
LogError(ex, "video reparsing error")
|
||||
ProcessException(ex, Token, "video reparsing error", False)
|
||||
End Try
|
||||
End Sub
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||
@@ -433,7 +408,7 @@ Namespace API.Reddit
|
||||
Try
|
||||
If Not URL.IsEmptyString AndAlso URL.StringContains({".jpg", ".png", ".jpeg"}) Then
|
||||
Dim f As SFile = CStr(RegexReplace(URL, FilesPattern))
|
||||
Return Not f.IsEmptyString And Not f.File.IsEmptyString
|
||||
Return Not f.File.IsEmptyString
|
||||
End If
|
||||
Return False
|
||||
Catch ex As Exception
|
||||
@@ -454,7 +429,7 @@ Namespace API.Reddit
|
||||
If _ContentNew.Count > 0 Then
|
||||
MyFile.Exists(SFO.Path)
|
||||
Dim MyDir$
|
||||
If IsChannel And SaveToCache Then
|
||||
If Not IsSavedPosts AndAlso (IsChannel And SaveToCache) Then
|
||||
MyDir = ChannelInfo.CachePath.PathNoSeparator
|
||||
Else
|
||||
MyDir = MyFile.CutPath.PathNoSeparator
|
||||
@@ -605,29 +580,20 @@ Namespace API.Reddit
|
||||
HasError = True
|
||||
End Try
|
||||
End Sub
|
||||
Protected Function GetSiteResponse(ByVal URL As String, Optional ByVal e As ErrorsDescriber = Nothing) As String
|
||||
Try
|
||||
Return Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
Catch ex As Exception
|
||||
HasError = True
|
||||
Dim OptText$ = String.Empty
|
||||
If Not e.Exists Then
|
||||
Dim ee As EDP = EDP.SendInLog
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
ee = EDP.ThrowException
|
||||
OptText = ": USER NOT FOUND"
|
||||
ex.HelpLink = NonExistendUserHelp
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.Forbidden Then
|
||||
ee = EDP.ThrowException
|
||||
OptText = ": USER PROFILE SUSPENDED"
|
||||
ex.HelpLink = SuspendedUserHelp
|
||||
Else
|
||||
ee += EDP.ReturnValue
|
||||
End If
|
||||
e = New ErrorsDescriber(ee)
|
||||
End If
|
||||
Return ErrorsDescriber.Execute(e, ex, $"[{Site} - {Name}: GetSiteResponse([{URL}])]{OptText}", String.Empty)
|
||||
End Try
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.Forbidden Then
|
||||
UserSuspended = True
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.BadGateway Or
|
||||
Responser.StatusCode = HttpStatusCode.ServiceUnavailable Or
|
||||
Responser.StatusCode = HttpStatusCode.GatewayTimeout Then
|
||||
MyMainLOG = "Reddit is currently unavailable"
|
||||
Else
|
||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||
Return 0
|
||||
End If
|
||||
Return 1
|
||||
End Function
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If Not disposedValue And disposing Then ChannelPostsNames.Clear() : _ExistsUsersNames.Clear()
|
||||
|
||||
22
SCrawler/API/Redgifs/Declarations.vb
Normal file
22
SCrawler/API/Redgifs/Declarations.vb
Normal file
@@ -0,0 +1,22 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.RedGifs
|
||||
Friend Module Declarations
|
||||
Friend ReadOnly DateProvider As New JsonDate
|
||||
Friend Class JsonDate : Implements ICustomProvider
|
||||
Friend Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||
Return ADateTime.ParseUnicode(Value, NothingArg, e)
|
||||
End Function
|
||||
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
|
||||
Throw New NotImplementedException("GetFormat is not available in this context")
|
||||
End Function
|
||||
End Class
|
||||
End Module
|
||||
End Namespace
|
||||
90
SCrawler/API/Redgifs/UserData.vb
Normal file
90
SCrawler/API/Redgifs/UserData.vb
Normal file
@@ -0,0 +1,90 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
||||
Imports System.Threading
|
||||
Imports System.Net
|
||||
Imports SCrawler.API.Base
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.RedGifs
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Friend Overrides Property Site As Sites = Sites.RedGifs
|
||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True)
|
||||
User = u
|
||||
If _LoadUserInformation Then LoadUserInformation()
|
||||
End Sub
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
DownloadData(1, Token)
|
||||
End Sub
|
||||
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Try
|
||||
URL = $"https://api.redgifs.com/v2/users/{Name}/search?order=recent&page={Page}"
|
||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
Dim postDate$, postID$
|
||||
Dim pTotal% = 0
|
||||
Dim u$
|
||||
Dim ut As UTypes
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
If j.Contains("gifs") Then
|
||||
pTotal = j.Value("pages").FromXML(Of Integer)(0)
|
||||
For Each g As EContainer In j("gifs")
|
||||
postDate = g.Value("createDate")
|
||||
postID = g.Value("id")
|
||||
If Not _TempPostsList.Contains(postID) Then _TempPostsList.Add(postID) Else Exit For
|
||||
With g("urls")
|
||||
If .ListExists Then
|
||||
u = If(.Item("hd"), .Item("sd")).XmlIfNothingValue
|
||||
If Not u.IsEmptyString Then
|
||||
ut = UTypes.Undefined
|
||||
'Type 1: video
|
||||
'Type 2: image
|
||||
Select Case g.Value("type").FromXML(Of Integer)(0)
|
||||
Case 1 : ut = UTypes.Video
|
||||
Case 2 : ut = UTypes.Picture
|
||||
End Select
|
||||
If Not ut = UTypes.Undefined Then _TempMediaList.ListAddValue(MediaFromData(ut, u, postID, postDate))
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
Next
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
If pTotal > 0 And Page < pTotal Then DownloadData(Page + 1, Token)
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
DownloadContentDefault(Token)
|
||||
End Sub
|
||||
Private Shared Function MediaFromData(ByVal t As UTypes, ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String) As UserMedia
|
||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID}}
|
||||
If Not m.URL.IsEmptyString Then m.File = CStr(RegexReplace(m.URL, FilesPattern)) : m.URL_BASE = m.URL
|
||||
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateProvider, Nothing) Else m.Post.Date = Nothing
|
||||
Return m
|
||||
End Function
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
Else
|
||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||
Return 0
|
||||
End If
|
||||
Return 1
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -12,35 +12,10 @@ Imports PersonalUtilities.Functions.XML
|
||||
Imports System.Net
|
||||
Imports System.Threading
|
||||
Imports SCrawler.API.Base
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
Namespace API.Twitter
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
#Region "Declarations"
|
||||
Friend Overrides Property Site As Sites = Sites.Twitter
|
||||
Private Structure Sizes : Implements IComparable(Of Sizes)
|
||||
Friend Value As Integer
|
||||
Friend Name As String
|
||||
Friend ReadOnly HasError As Boolean
|
||||
Friend Sub New(ByVal _Value As String, ByVal _Name As String)
|
||||
Try
|
||||
Value = _Value
|
||||
Name = _Name
|
||||
Catch ex As Exception
|
||||
HasError = True
|
||||
End Try
|
||||
End Sub
|
||||
Friend Function CompareTo(ByVal Other As Sizes) As Integer Implements IComparable(Of Sizes).CompareTo
|
||||
Return Value.CompareTo(Other.Value) * -1
|
||||
End Function
|
||||
Friend Shared Function Reparse(ByRef Current As Sizes, ByVal Other As Sizes, ByVal LargeContained As Boolean) As Sizes
|
||||
If LargeContained And Current.Name.IsEmptyString And Current.Value > Other.Value Then Current.Name = "large"
|
||||
Return Current
|
||||
End Function
|
||||
Friend Shared Function ApplyLarge(ByRef s As Sizes) As Sizes
|
||||
s.Name = "large"
|
||||
Return s
|
||||
End Function
|
||||
End Structure
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True)
|
||||
@@ -48,6 +23,10 @@ Namespace API.Twitter
|
||||
If _LoadUserInformation Then LoadUserInformation()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Load and Update user info"
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download functions"
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
DownloadData(String.Empty, Token)
|
||||
@@ -115,19 +94,8 @@ Namespace API.Twitter
|
||||
If POST.IsEmptyString And ExistsDetected Then Exit Sub
|
||||
If Not PostID.IsEmptyString And NewPostDetected Then DownloadData(PostID, Token)
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.Unauthorized Then
|
||||
UserSuspended = True
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
MyMainLOG = "Twitter has invalid credentials"
|
||||
Else
|
||||
LogError(ex, $"data downloading error [{URL}]")
|
||||
HasError = True
|
||||
End If
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||
@@ -164,12 +132,12 @@ Namespace API.Twitter
|
||||
Next
|
||||
If l.Count > 0 Then
|
||||
l.Sort()
|
||||
If l(0).Name.IsEmptyString And LargeContained Then Return "large" Else Return l(0).Name
|
||||
If l(0).Data.IsEmptyString And LargeContained Then Return "large" Else Return l(0).Data
|
||||
End If
|
||||
End If
|
||||
Return String.Empty
|
||||
Catch ex As Exception
|
||||
LogError(ex, "[GetPictureOption]")
|
||||
LogError(ex, "[API.Twitter.UserData.GetPictureOption]")
|
||||
Return String.Empty
|
||||
End Try
|
||||
End Function
|
||||
@@ -181,7 +149,7 @@ Namespace API.Twitter
|
||||
If Not URL.IsEmptyString Then _TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate), LNC) : Return True
|
||||
Return False
|
||||
Catch ex As Exception
|
||||
LogError(ex, "[CheckVideoNode]")
|
||||
LogError(ex, "[API.Twitter.UserData.CheckVideoNode]")
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
@@ -202,7 +170,7 @@ Namespace API.Twitter
|
||||
End If
|
||||
Next
|
||||
If l.Count > 0 Then l.RemoveAll(Function(s) s.HasError)
|
||||
If l.Count > 0 Then l.Sort() : Return l(0).Name
|
||||
If l.Count > 0 Then l.Sort() : Return l(0).Data
|
||||
End If
|
||||
Return String.Empty
|
||||
End Function
|
||||
@@ -222,70 +190,20 @@ Namespace API.Twitter
|
||||
End Function
|
||||
#End Region
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
Try
|
||||
Dim i%
|
||||
Dim dCount% = 0, dTotal% = 0
|
||||
ThrowAny(Token)
|
||||
If _ContentNew.Count > 0 Then
|
||||
_ContentNew.RemoveAll(Function(c) c.URL.IsEmptyString)
|
||||
If _ContentNew.Count > 0 Then
|
||||
MyFile.Exists(SFO.Path)
|
||||
Dim MyDir$ = MyFile.CutPath.PathNoSeparator
|
||||
Dim vsf As Boolean = SeparateVideoFolderF
|
||||
Dim f As SFile
|
||||
Dim v As UserMedia
|
||||
Using w As New WebClient
|
||||
If vsf Then SFileShares.SFileExists($"{MyDir}\Video\", SFO.Path)
|
||||
MainProgress.TotalCount += _ContentNew.Count
|
||||
For i = 0 To _ContentNew.Count - 1
|
||||
ThrowAny(Token)
|
||||
v = _ContentNew(i)
|
||||
v.State = UStates.Tried
|
||||
If v.File.IsEmptyString Then
|
||||
f = v.URL
|
||||
Else
|
||||
f = v.File
|
||||
End If
|
||||
f.Separator = "\"
|
||||
f.Path = MyDir
|
||||
|
||||
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
||||
|
||||
If Not v.File.IsEmptyString AndAlso Not v.URL_BASE.IsEmptyString Then
|
||||
Try
|
||||
If f.Extension = "mp4" And vsf Then f.Path = $"{f.PathWithSeparator}Video"
|
||||
w.DownloadFile(v.URL_BASE, f.ToString)
|
||||
Select Case f.Extension
|
||||
Case "mp4" : v.Type = UserMedia.Types.Video : DownloadedVideos += 1 : _CountVideo += 1
|
||||
Case Else : v.Type = UserMedia.Types.Picture : DownloadedPictures += 1 : _CountPictures += 1
|
||||
End Select
|
||||
v.File = ChangeFileNameByProvider(f, v)
|
||||
v.State = UStates.Downloaded
|
||||
dCount += 1
|
||||
Catch wex As Exception
|
||||
ErrorDownloading(f, v.URL_BASE)
|
||||
End Try
|
||||
Else
|
||||
v.State = UStates.Skipped
|
||||
End If
|
||||
_ContentNew(i) = v
|
||||
If DownloadTopCount.HasValue AndAlso dCount >= DownloadTopCount.Value Then
|
||||
MainProgress.Perform(_ContentNew.Count - dTotal)
|
||||
Exit Sub
|
||||
Else
|
||||
dTotal += 1
|
||||
MainProgress.Perform()
|
||||
End If
|
||||
Next
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Catch ex As Exception
|
||||
LogError(ex, "content downloading error")
|
||||
HasError = True
|
||||
End Try
|
||||
DownloadContentDefault(Token)
|
||||
End Sub
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.Unauthorized Then
|
||||
UserSuspended = True
|
||||
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
MyMainLOG = "Twitter has invalid credentials"
|
||||
Else
|
||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||
Return 0
|
||||
End If
|
||||
Return 1
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -7,6 +7,7 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports System.Threading
|
||||
Imports SCrawler.API.Base
|
||||
Namespace API
|
||||
@@ -271,6 +272,8 @@ Namespace API
|
||||
Friend Overrides Sub LoadContentInformation()
|
||||
If Count > 0 Then Collections.ForEach(Sub(c) DirectCast(c.Self, UserDataBase).LoadContentInformation())
|
||||
End Sub
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
End Sub
|
||||
Friend Overrides Property DownloadTopCount As Integer?
|
||||
Get
|
||||
If Count > 0 Then
|
||||
@@ -292,6 +295,9 @@ Namespace API
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
End Sub
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
|
||||
Return 0
|
||||
End Function
|
||||
Private Sub User_OnUserUpdated(ByVal User As IUserData)
|
||||
Raise_OnUserUpdated()
|
||||
End Sub
|
||||
@@ -338,16 +344,16 @@ Namespace API
|
||||
End Sub
|
||||
''' <summary>FOR SETTINGS START LOADING ONLY</summary>
|
||||
Friend Overloads Sub Add(ByVal u As UserInfo, Optional ByVal _LoadData As Boolean = True)
|
||||
Select Case u.Site
|
||||
Case Sites.Reddit : Collections.Add(New Reddit.UserData(u, _LoadData))
|
||||
Case Sites.Twitter : Collections.Add(New Twitter.UserData(u, _LoadData))
|
||||
Case Else : Exit Sub
|
||||
End Select
|
||||
With DirectCast(Collections.Last.Self, UserDataBase)
|
||||
.CreateButtons(Count - 1)
|
||||
AddHandler .BTT_CONTEXT_DELETE.Click, AddressOf BTT_CONTEXT_DELETE_Click
|
||||
End With
|
||||
AddHandler Collections.Last.OnUserUpdated, AddressOf User_OnUserUpdated
|
||||
Collections.Add(GetInstance(u, _LoadData))
|
||||
If Not Collections.Last Is Nothing Then
|
||||
With DirectCast(Collections.Last.Self, UserDataBase)
|
||||
.CreateButtons(Count - 1)
|
||||
AddHandler .BTT_CONTEXT_DELETE.Click, AddressOf BTT_CONTEXT_DELETE_Click
|
||||
End With
|
||||
AddHandler Collections.Last.OnUserUpdated, AddressOf User_OnUserUpdated
|
||||
Else
|
||||
Collections.RemoveAt(Count - 1)
|
||||
End If
|
||||
End Sub
|
||||
Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData))
|
||||
If Not _Items Is Nothing AndAlso _Items.Count > 0 Then
|
||||
|
||||
@@ -19,20 +19,26 @@ Imports CmbDefaultButtons = PersonalUtilities.Forms.Controls.Base.ActionButton.D
|
||||
Imports RButton = PersonalUtilities.Tools.RangeSwitcherButton.Types
|
||||
Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
Friend Event OnUsersAdded(ByVal StartIndex As Integer)
|
||||
Friend Event OnDownloadDone(ByVal Message As String)
|
||||
#Region "Appended user structure"
|
||||
Private Structure PendingUser
|
||||
Friend ID As String
|
||||
Friend File As SFile
|
||||
Friend Sub New(ByVal _ID As String, Optional ByVal _File As SFile = Nothing)
|
||||
Friend Channel As Channel
|
||||
Friend Sub New(ByVal _ID As String, ByRef _Channel As Channel, Optional ByVal _File As SFile = Nothing)
|
||||
ID = _ID
|
||||
Channel = _Channel
|
||||
If Settings.FromChannelCopyImageToUser Then File = _File
|
||||
End Sub
|
||||
Public Shared Widening Operator CType(ByVal _ID As String) As PendingUser
|
||||
Return New PendingUser(_ID, False)
|
||||
Return New PendingUser(_ID, Nothing)
|
||||
End Operator
|
||||
Public Shared Widening Operator CType(ByVal u As PendingUser) As String
|
||||
Return u.ToString
|
||||
End Operator
|
||||
Friend Sub ChannelUserAdded(Optional ByVal IsAdded As Boolean = True)
|
||||
If Not Channel Is Nothing Then Channel.UserAdded(IsAdded)
|
||||
End Sub
|
||||
Public Overrides Function ToString() As String
|
||||
Return ID
|
||||
End Function
|
||||
@@ -53,6 +59,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
Private WithEvents OPT_LIMITS_COUNT As RadioButton
|
||||
Private WithEvents OPT_LIMITS_POST As RadioButton
|
||||
Private WithEvents OPT_LIMITS_DATE As RadioButton
|
||||
Private WithEvents BTT_SHOW_STATS As ToolStripButton
|
||||
#End Region
|
||||
Private ReadOnly CProvider As ANumbers
|
||||
Private ReadOnly CProgress As MyProgress
|
||||
@@ -134,7 +141,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormProps
|
||||
CProgress = New MyProgress(ToolbarBOTTOM, PR_CN, LBL_STATUS, "Downloading data") With {.PerformMod = 10, .DropCurrentProgressOnTotalChange = False}
|
||||
CProvider = New ANumbers(ANumbers.Modes.USA) With {.GroupSize = 3, .DecimalDigits = 0}
|
||||
CProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||
LimitProvider = New ADateTime("dd.MM.yyyy HH:mm")
|
||||
PendingUsers = New List(Of PendingUser)
|
||||
|
||||
@@ -149,7 +156,8 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
}
|
||||
CMB_CHANNELS.Buttons.AddRange({CmbDefaultButtons.Refresh, CmbDefaultButtons.Add, CmbDefaultButtons.Delete,
|
||||
New ActionButton(CmbDefaultButtons.Up) With {.ToolTipText = "Previous item (F1)"},
|
||||
New ActionButton(CmbDefaultButtons.Down) With {.ToolTipText = "Next item (F4)"}})
|
||||
New ActionButton(CmbDefaultButtons.Down) With {.ToolTipText = "Next item (F4)"},
|
||||
CmbDefaultButtons.Info})
|
||||
TXT_LIMIT = New TextBoxExtended With {
|
||||
.CaptionText = "Limit",
|
||||
.Margin = New Padding(2),
|
||||
@@ -168,6 +176,9 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
OPT_LIMITS_DATE = New RadioButton With {.Text = "Date", .BackColor = Color.Transparent, .Margin = New Padding(2)}
|
||||
CH_HIDE_EXISTS_USERS = New CheckBox With {.Text = "Hide exists users", .BackColor = Color.Transparent, .Margin = New Padding(2),
|
||||
.Checked = Settings.ChannelsHideExistsUser}
|
||||
BTT_SHOW_STATS = New ToolStripButton With {.Text = "Info", .Image = PersonalUtilities.My.Resources.InfoPic_32,
|
||||
.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText, .Alignment = ToolStripItemAlignment.Right,
|
||||
.AutoToolTip = True, .ToolTipText = "Show channels statistic"}
|
||||
|
||||
TT_MAIN.SetToolTip(CH_HIDE_EXISTS_USERS, "Hide users which already exists in collection")
|
||||
TT_MAIN.SetToolTip(OPT_LIMITS_COUNT, "Total posts count limit")
|
||||
@@ -182,8 +193,9 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
TXT_LIMIT.GetControlHost,
|
||||
LBL_LIMIT_TEXT,
|
||||
New ToolStripSeparator,
|
||||
New ToolStripControlHost(CH_HIDE_EXISTS_USERS)})
|
||||
MyRange = New RangeSwitcher(Of UserPost) With {.Selector = Function(p) Not Settings.UserExists(Sites.Reddit, p.UserID)}
|
||||
New ToolStripControlHost(CH_HIDE_EXISTS_USERS),
|
||||
BTT_SHOW_STATS})
|
||||
MyRange = New RangeSwitcher(Of UserPost) With {.Selector = SelectorExpression}
|
||||
With MyRange
|
||||
.Limit = ImagesInRow * ImagesRows
|
||||
.InsertButtons(ToolbarTOP, {RButton.Previous, RButton.Next}, 5)
|
||||
@@ -192,7 +204,6 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
.BindForm(Me)
|
||||
.LabelNumbersProvider = CProvider
|
||||
.UpdateControls()
|
||||
.Selector = SelectorExpression
|
||||
End With
|
||||
AddHandler Settings.ChannelsImagesColumns.OnValueChanged, AddressOf ImagesCountChanged
|
||||
AddHandler Settings.ChannelsImagesRows.OnValueChanged, AddressOf ImagesCountChanged
|
||||
@@ -225,6 +236,8 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
OPT_LIMITS_COUNT.Dispose()
|
||||
OPT_LIMITS_POST.Dispose()
|
||||
LBL_LIMIT_TEXT.Dispose()
|
||||
BTT_SHOW_STATS.Dispose()
|
||||
MyRange.Dispose()
|
||||
PendingUsers.Clear()
|
||||
MyDefs.Dispose()
|
||||
End Sub
|
||||
@@ -266,9 +279,11 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
#Region "Images refill methods"
|
||||
Private Sub AppendPendingUsers()
|
||||
If LIST_POSTS.CheckedIndices.Count > 0 Then
|
||||
Dim c As Channel = GetCurrentChannel(False)
|
||||
Dim lp As New ListAddParams(LAP.NotContainsOnly) With {.OnAddAction = Sub(ByVal u As PendingUser) u.ChannelUserAdded()}
|
||||
PendingUsers.ListAddList((From p As ListViewItem In LIST_POSTS.Items
|
||||
Where p.Checked
|
||||
Select New PendingUser(p.Text, GetPostBySelected(CStr(p.Tag)).CachedFile)), LNC)
|
||||
Select New PendingUser(p.Text, c, GetPostBySelected(CStr(p.Tag)).CachedFile)), lp)
|
||||
Dim a As Action = Sub() BTT_ADD_USERS.Text = $"Add ({PendingUsers.Count.ToString(CProvider)})"
|
||||
If ToolbarTOP.InvokeRequired Then ToolbarTOP.Invoke(a) Else a.Invoke
|
||||
End If
|
||||
@@ -324,6 +339,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
TXT_LIMIT.Enabled = False
|
||||
CH_HIDE_EXISTS_USERS.Enabled = False
|
||||
CMB_CHANNELS.Enabled(True) = False
|
||||
BTT_SHOW_STATS.Enabled = False
|
||||
MyRange.EnableButton(RButton.Previous, False)
|
||||
MyRange.EnableButton(RButton.Next, False)
|
||||
End If
|
||||
@@ -337,6 +353,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
_CollectionDownloading = True
|
||||
Settings.Channels.SetLimit(Me)
|
||||
Await Task.Run(Sub() Settings.Channels.DownloadData(Token, CH_HIDE_EXISTS_USERS.Checked, CProgress))
|
||||
RaiseEvent OnDownloadDone("All channels downloaded")
|
||||
Token.ThrowIfCancellationRequested()
|
||||
c = GetCurrentChannel()
|
||||
Else
|
||||
@@ -345,6 +362,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
InvokeToken.Invoke()
|
||||
c.SetLimit(Me)
|
||||
Await Task.Run(Sub() c.DownloadData(Token, CH_HIDE_EXISTS_USERS.Checked, CProgress))
|
||||
RaiseEvent OnDownloadDone($"Channel [{c.Name}] downloaded")
|
||||
Token.ThrowIfCancellationRequested()
|
||||
End If
|
||||
End If
|
||||
@@ -377,6 +395,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
TXT_LIMIT.Enabled = True
|
||||
CH_HIDE_EXISTS_USERS.Enabled = True
|
||||
CMB_CHANNELS.Enabled(True) = True
|
||||
BTT_SHOW_STATS.Enabled = True
|
||||
CMB_CHANNELS_ActionOnCheckedChange(CMB_CHANNELS.Checked)
|
||||
With MyRange
|
||||
.EnableButton(RButton.Previous, .Count > 0 AndAlso .CurrentIndex > 0)
|
||||
@@ -524,12 +543,13 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
If Not c Is Nothing Then MyRange.ChangeSource(c, EDP.SendInLog)
|
||||
End Sub
|
||||
Private Sub CMB_CHANNELS_ActionOnButtonClick(ByVal Sender As ActionButton) Handles CMB_CHANNELS.ActionOnButtonClick
|
||||
Dim c As Channel
|
||||
Select Case Sender.DefaultButton
|
||||
Case CmbDefaultButtons.Refresh : RefillChannels()
|
||||
Case CmbDefaultButtons.Add : AddNewChannel()
|
||||
Case CmbDefaultButtons.Delete
|
||||
Try
|
||||
Dim c As Channel = GetCurrentChannel()
|
||||
c = GetCurrentChannel()
|
||||
If Not c Is Nothing AndAlso MsgBoxE($"Do you really want to delete channel [{c}]?", MsgBoxStyle.Exclamation + MsgBoxStyle.YesNo) = 0 Then
|
||||
Settings.Channels.Remove(c)
|
||||
RefillChannels()
|
||||
@@ -539,6 +559,13 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
End Try
|
||||
Case CmbDefaultButtons.Up : ChangeComboIndex(-1)
|
||||
Case CmbDefaultButtons.Down : ChangeComboIndex(1)
|
||||
Case CmbDefaultButtons.Info
|
||||
Try
|
||||
c = GetCurrentChannel()
|
||||
If Not c Is Nothing Then MsgBoxE({c.GetChannelStats(True), "Channel statistics"})
|
||||
Catch info_ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.LogMessageValue, info_ex, "Error on trying to show channel info")
|
||||
End Try
|
||||
End Select
|
||||
End Sub
|
||||
Private Sub CMB_CHANNELS_ActionOnCheckedChange(ByVal Mode As Boolean) Handles CMB_CHANNELS.ActionOnCheckedChange
|
||||
@@ -602,6 +629,12 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
MyRange.Update()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub BTT_SHOW_STATS_Click(sender As Object, e As EventArgs) Handles BTT_SHOW_STATS.Click
|
||||
Using f As New ChannelsStatsForm
|
||||
f.ShowDialog()
|
||||
If f.DeletedChannels > 0 Then RefillChannels()
|
||||
End Using
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "CONTEXT"
|
||||
Private Sub BTT_C_OPEN_USER_Click(sender As Object, e As EventArgs) Handles BTT_C_OPEN_USER.Click
|
||||
@@ -634,10 +667,14 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
Dim u$ = GetPostBySelected().UserID
|
||||
If Not u.IsEmptyString Then
|
||||
Dim uRemoved As Boolean = False
|
||||
If PendingUsers.Contains(u) Then PendingUsers.Remove(u) : uRemoved = True
|
||||
Dim i% = PendingUsers.IndexOf(u)
|
||||
If i >= 0 Then
|
||||
PendingUsers(i).ChannelUserAdded(False)
|
||||
PendingUsers.RemoveAt(i)
|
||||
uRemoved = True
|
||||
End If
|
||||
With LIST_POSTS
|
||||
If .Items.Count > 0 Then
|
||||
Dim i%
|
||||
Dim a As Action = Sub() .Items(i).Checked = False
|
||||
For i = 0 To .Items.Count - 1
|
||||
If .Items(i).Text = u And .Items(i).Checked Then
|
||||
|
||||
112
SCrawler/Channels/ChannelsStatsForm.Designer.vb
generated
Normal file
112
SCrawler/Channels/ChannelsStatsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,112 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class ChannelsStatsForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ChannelsStatsForm))
|
||||
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
|
||||
Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
|
||||
Me.CMB_CHANNELS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
CType(Me.CMB_CHANNELS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.CMB_CHANNELS)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 261)
|
||||
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||
CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 261)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
'CMB_CHANNELS
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Index = 0
|
||||
ActionButton1.Name = "BTT_COMBOBOX_ARROW"
|
||||
ActionButton1.Visible = False
|
||||
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton2.Index = 1
|
||||
ActionButton2.Name = "BTT_CLEAR"
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Index = 2
|
||||
ActionButton3.Name = "BTT_DELETE"
|
||||
Me.CMB_CHANNELS.Buttons.Add(ActionButton1)
|
||||
Me.CMB_CHANNELS.Buttons.Add(ActionButton2)
|
||||
Me.CMB_CHANNELS.Buttons.Add(ActionButton3)
|
||||
Me.CMB_CHANNELS.ClearTextByButtonClear = False
|
||||
ListColumn1.DisplayMember = True
|
||||
ListColumn1.Name = "COL_INFO"
|
||||
ListColumn1.Text = "Information"
|
||||
ListColumn1.Width = -2
|
||||
ListColumn2.Name = "COL_VALUE"
|
||||
ListColumn2.Text = "Channel"
|
||||
ListColumn2.ValueMember = True
|
||||
ListColumn2.Visible = False
|
||||
Me.CMB_CHANNELS.Columns.Add(ListColumn1)
|
||||
Me.CMB_CHANNELS.Columns.Add(ListColumn2)
|
||||
Me.CMB_CHANNELS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CMB_CHANNELS.ListCheckBoxes = True
|
||||
Me.CMB_CHANNELS.ListDropDownStyle = PersonalUtilities.Forms.Controls.ComboBoxExtended.ListMode.Simple
|
||||
Me.CMB_CHANNELS.ListGridVisible = True
|
||||
Me.CMB_CHANNELS.ListMultiSelect = True
|
||||
Me.CMB_CHANNELS.Location = New System.Drawing.Point(0, 0)
|
||||
Me.CMB_CHANNELS.Name = "CMB_CHANNELS"
|
||||
Me.CMB_CHANNELS.Size = New System.Drawing.Size(386, 262)
|
||||
Me.CMB_CHANNELS.TabIndex = 0
|
||||
'
|
||||
'ChannelsStatsForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(384, 261)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
||||
Me.KeyPreview = True
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(400, 300)
|
||||
Me.Name = "ChannelsStatsForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.Text = "Channels statistics"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
CType(Me.CMB_CHANNELS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents CMB_CHANNELS As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||
End Class
|
||||
1383
SCrawler/Channels/ChannelsStatsForm.resx
Normal file
1383
SCrawler/Channels/ChannelsStatsForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
84
SCrawler/Channels/ChannelsStatsForm.vb
Normal file
84
SCrawler/Channels/ChannelsStatsForm.vb
Normal file
@@ -0,0 +1,84 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Controls.Base
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Friend Class ChannelsStatsForm : Implements IOkCancelDeleteToolbar
|
||||
Private ReadOnly MyDefs As DefaultFormProps
|
||||
Friend Property DeletedChannels As Integer = 0
|
||||
Friend Sub New()
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormProps
|
||||
End Sub
|
||||
Private Sub ChannelsStatsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
Try
|
||||
With MyDefs
|
||||
.MyViewInitialize(Me, Settings.Design)
|
||||
.AddOkCancelToolbar()
|
||||
.DelegateClosingChecker()
|
||||
.MyOkCancel.EnableDelete = False
|
||||
If Settings.Channels.Count > 0 Then
|
||||
RefillList()
|
||||
Else
|
||||
MsgBoxE("Channels not found", vbExclamation)
|
||||
End If
|
||||
.AppendDetectors()
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
Catch ex As Exception
|
||||
MyDefs.InvokeLoaderError(ex)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub ChannelsStatsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||
MyDefs.Dispose()
|
||||
End Sub
|
||||
Private Sub RefillList()
|
||||
CMB_CHANNELS.Items.Clear()
|
||||
If Settings.Channels.Count > 0 Then
|
||||
CMB_CHANNELS.BeginUpdate()
|
||||
CMB_CHANNELS.Items.AddRange(Settings.Channels.Select(Function(c) New ListItem({$"[{c.ID}]: {c.GetChannelStats(False)}", c.ID})))
|
||||
CMB_CHANNELS.EndUpdate()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
Private Sub ToolbarBttCancel() Implements IOkCancelToolbar.ToolbarBttCancel
|
||||
MyDefs.CloseForm(DialogResult.Cancel)
|
||||
End Sub
|
||||
Private Sub ToolbarBttDelete() Implements IOkCancelDeleteToolbar.ToolbarBttDelete
|
||||
Try
|
||||
Dim c As List(Of String) = CMB_CHANNELS.Items.CheckedItems.Select(Function(cc) CStr(cc.Value(1))).ListIfNothing
|
||||
If c.ListExists Then
|
||||
If MsgBoxE({$"The following channels will be deleted:{vbCr}{c.ListToString(, vbCr)}", "Deleting channels"}, vbExclamation,,, {"Confirm", "Cancel"}) = 0 Then
|
||||
For Each CID$ In c : Settings.Channels.Remove(Settings.Channels.Find(CID)) : Next
|
||||
MyMainLOG = $"Deleted channels:{vbNewLine}{c.ListToString(, vbNewLine)}"
|
||||
MsgBoxE("Channels deleted")
|
||||
DeletedChannels += c.Count
|
||||
c.Clear()
|
||||
MyDefs.ChangesDetected = False
|
||||
RefillList()
|
||||
Else
|
||||
MsgBoxE("Operation canceled")
|
||||
End If
|
||||
Else
|
||||
MsgBoxE("No one channel checked", vbExclamation)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Deleting channels")
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub CMB_CHANNELS_ActionOnChangeDetected(ByVal c As Boolean) Handles CMB_CHANNELS.ActionOnChangeDetected
|
||||
If Not MyDefs.Initializing Then MyDefs.MyOkCancel.EnableDelete = CMB_CHANNELS.ListCheckedIndexes.Count > 0
|
||||
End Sub
|
||||
Private Sub CMB_CHANNELS_ActionOnButtonClearClick() Handles CMB_CHANNELS.ActionOnButtonClearClick
|
||||
CMB_CHANNELS.ListCheckedIndexes = Nothing
|
||||
End Sub
|
||||
End Class
|
||||
BIN
SCrawler/Content/Icons/BookmarkIcon_32.ico
Normal file
BIN
SCrawler/Content/Icons/BookmarkIcon_32.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
SCrawler/Content/Pictures/HeartPic_32.png
Normal file
BIN
SCrawler/Content/Pictures/HeartPic_32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 525 B |
336
SCrawler/DownloadSavedPostsForm.Designer.vb
generated
Normal file
336
SCrawler/DownloadSavedPostsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,336 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class DownloadSavedPostsForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_REDDIT As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_REDDIT_PR As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_INST As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_INST_PR As System.Windows.Forms.TableLayoutPanel
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadSavedPostsForm))
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.BTT_DOWN_ALL = New System.Windows.Forms.Button()
|
||||
Me.BTT_STOP_ALL = New System.Windows.Forms.Button()
|
||||
Me.BTT_REDDIT_START = New System.Windows.Forms.Button()
|
||||
Me.BTT_REDDIT_STOP = New System.Windows.Forms.Button()
|
||||
Me.PR_REDDIT = New System.Windows.Forms.ProgressBar()
|
||||
Me.BTT_REDDIT_OPEN = New System.Windows.Forms.Button()
|
||||
Me.LBL_REDDIT = New System.Windows.Forms.Label()
|
||||
Me.BTT_INST_START = New System.Windows.Forms.Button()
|
||||
Me.BTT_INST_STOP = New System.Windows.Forms.Button()
|
||||
Me.PR_INST = New System.Windows.Forms.ProgressBar()
|
||||
Me.BTT_INST_OPEN = New System.Windows.Forms.Button()
|
||||
Me.LBL_INST = New System.Windows.Forms.Label()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_REDDIT = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_REDDIT_PR = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_INST = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_INST_PR = New System.Windows.Forms.TableLayoutPanel()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
TP_MAIN.SuspendLayout()
|
||||
TP_BUTTONS.SuspendLayout()
|
||||
TP_REDDIT.SuspendLayout()
|
||||
TP_REDDIT_PR.SuspendLayout()
|
||||
TP_INST.SuspendLayout()
|
||||
TP_INST_PR.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Inset
|
||||
TP_MAIN.ColumnCount = 1
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Controls.Add(TP_BUTTONS, 0, 0)
|
||||
TP_MAIN.Controls.Add(TP_REDDIT, 0, 1)
|
||||
TP_MAIN.Controls.Add(TP_INST, 0, 2)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 3
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(484, 156)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_BUTTONS
|
||||
'
|
||||
TP_BUTTONS.ColumnCount = 2
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_DOWN_ALL, 0, 0)
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_STOP_ALL, 1, 0)
|
||||
TP_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_BUTTONS.Location = New System.Drawing.Point(2, 2)
|
||||
TP_BUTTONS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_BUTTONS.Name = "TP_BUTTONS"
|
||||
TP_BUTTONS.RowCount = 1
|
||||
TP_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_BUTTONS.Size = New System.Drawing.Size(480, 30)
|
||||
TP_BUTTONS.TabIndex = 0
|
||||
'
|
||||
'BTT_DOWN_ALL
|
||||
'
|
||||
Me.BTT_DOWN_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_DOWN_ALL.Location = New System.Drawing.Point(3, 3)
|
||||
Me.BTT_DOWN_ALL.Name = "BTT_DOWN_ALL"
|
||||
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(234, 24)
|
||||
Me.BTT_DOWN_ALL.TabIndex = 0
|
||||
Me.BTT_DOWN_ALL.Text = "Download ALL"
|
||||
Me.BTT_DOWN_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_STOP_ALL
|
||||
'
|
||||
Me.BTT_STOP_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_STOP_ALL.Location = New System.Drawing.Point(243, 3)
|
||||
Me.BTT_STOP_ALL.Name = "BTT_STOP_ALL"
|
||||
Me.BTT_STOP_ALL.Size = New System.Drawing.Size(234, 24)
|
||||
Me.BTT_STOP_ALL.TabIndex = 1
|
||||
Me.BTT_STOP_ALL.Text = "Stop ALL"
|
||||
Me.BTT_STOP_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_REDDIT
|
||||
'
|
||||
TP_REDDIT.ColumnCount = 1
|
||||
TP_REDDIT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_REDDIT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_REDDIT.Controls.Add(TP_REDDIT_PR, 0, 0)
|
||||
TP_REDDIT.Controls.Add(Me.LBL_REDDIT, 0, 1)
|
||||
TP_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_REDDIT.Location = New System.Drawing.Point(2, 34)
|
||||
TP_REDDIT.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_REDDIT.Name = "TP_REDDIT"
|
||||
TP_REDDIT.RowCount = 2
|
||||
TP_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_REDDIT.Size = New System.Drawing.Size(480, 59)
|
||||
TP_REDDIT.TabIndex = 1
|
||||
'
|
||||
'TP_REDDIT_PR
|
||||
'
|
||||
TP_REDDIT_PR.ColumnCount = 4
|
||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_REDDIT_PR.Controls.Add(Me.BTT_REDDIT_START, 0, 0)
|
||||
TP_REDDIT_PR.Controls.Add(Me.BTT_REDDIT_STOP, 1, 0)
|
||||
TP_REDDIT_PR.Controls.Add(Me.PR_REDDIT, 3, 0)
|
||||
TP_REDDIT_PR.Controls.Add(Me.BTT_REDDIT_OPEN, 2, 0)
|
||||
TP_REDDIT_PR.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_REDDIT_PR.Location = New System.Drawing.Point(0, 0)
|
||||
TP_REDDIT_PR.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_REDDIT_PR.Name = "TP_REDDIT_PR"
|
||||
TP_REDDIT_PR.RowCount = 1
|
||||
TP_REDDIT_PR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_REDDIT_PR.Size = New System.Drawing.Size(480, 29)
|
||||
TP_REDDIT_PR.TabIndex = 0
|
||||
'
|
||||
'BTT_REDDIT_START
|
||||
'
|
||||
Me.BTT_REDDIT_START.BackgroundImage = Global.SCrawler.My.Resources.Resources.StartPic_01_Green_16
|
||||
Me.BTT_REDDIT_START.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_REDDIT_START.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_REDDIT_START.Location = New System.Drawing.Point(3, 3)
|
||||
Me.BTT_REDDIT_START.Name = "BTT_REDDIT_START"
|
||||
Me.BTT_REDDIT_START.Size = New System.Drawing.Size(24, 23)
|
||||
Me.BTT_REDDIT_START.TabIndex = 0
|
||||
TT_MAIN.SetToolTip(Me.BTT_REDDIT_START, "Start downloading saved Reddit posts")
|
||||
Me.BTT_REDDIT_START.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_REDDIT_STOP
|
||||
'
|
||||
Me.BTT_REDDIT_STOP.BackgroundImage = Global.SCrawler.My.Resources.Resources.Delete
|
||||
Me.BTT_REDDIT_STOP.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_REDDIT_STOP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_REDDIT_STOP.Enabled = False
|
||||
Me.BTT_REDDIT_STOP.Location = New System.Drawing.Point(33, 3)
|
||||
Me.BTT_REDDIT_STOP.Name = "BTT_REDDIT_STOP"
|
||||
Me.BTT_REDDIT_STOP.Size = New System.Drawing.Size(24, 23)
|
||||
Me.BTT_REDDIT_STOP.TabIndex = 1
|
||||
TT_MAIN.SetToolTip(Me.BTT_REDDIT_STOP, "Stop downloading saved Reddit posts")
|
||||
Me.BTT_REDDIT_STOP.UseVisualStyleBackColor = True
|
||||
'
|
||||
'PR_REDDIT
|
||||
'
|
||||
Me.PR_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.PR_REDDIT.Location = New System.Drawing.Point(93, 3)
|
||||
Me.PR_REDDIT.Name = "PR_REDDIT"
|
||||
Me.PR_REDDIT.Size = New System.Drawing.Size(384, 23)
|
||||
Me.PR_REDDIT.TabIndex = 2
|
||||
'
|
||||
'BTT_REDDIT_OPEN
|
||||
'
|
||||
Me.BTT_REDDIT_OPEN.BackgroundImage = CType(resources.GetObject("BTT_REDDIT_OPEN.BackgroundImage"), System.Drawing.Image)
|
||||
Me.BTT_REDDIT_OPEN.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_REDDIT_OPEN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_REDDIT_OPEN.Location = New System.Drawing.Point(63, 3)
|
||||
Me.BTT_REDDIT_OPEN.Name = "BTT_REDDIT_OPEN"
|
||||
Me.BTT_REDDIT_OPEN.Size = New System.Drawing.Size(24, 23)
|
||||
Me.BTT_REDDIT_OPEN.TabIndex = 3
|
||||
Me.BTT_REDDIT_OPEN.UseVisualStyleBackColor = True
|
||||
'
|
||||
'LBL_REDDIT
|
||||
'
|
||||
Me.LBL_REDDIT.AutoSize = True
|
||||
Me.LBL_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_REDDIT.Location = New System.Drawing.Point(3, 29)
|
||||
Me.LBL_REDDIT.Name = "LBL_REDDIT"
|
||||
Me.LBL_REDDIT.Size = New System.Drawing.Size(474, 30)
|
||||
Me.LBL_REDDIT.TabIndex = 1
|
||||
Me.LBL_REDDIT.Text = "Reddit"
|
||||
Me.LBL_REDDIT.TextAlign = System.Drawing.ContentAlignment.TopCenter
|
||||
'
|
||||
'TP_INST
|
||||
'
|
||||
TP_INST.ColumnCount = 1
|
||||
TP_INST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_INST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_INST.Controls.Add(TP_INST_PR, 0, 0)
|
||||
TP_INST.Controls.Add(Me.LBL_INST, 0, 1)
|
||||
TP_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_INST.Location = New System.Drawing.Point(2, 95)
|
||||
TP_INST.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_INST.Name = "TP_INST"
|
||||
TP_INST.RowCount = 2
|
||||
TP_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_INST.Size = New System.Drawing.Size(480, 59)
|
||||
TP_INST.TabIndex = 2
|
||||
'
|
||||
'TP_INST_PR
|
||||
'
|
||||
TP_INST_PR.ColumnCount = 4
|
||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_INST_PR.Controls.Add(Me.BTT_INST_START, 0, 0)
|
||||
TP_INST_PR.Controls.Add(Me.BTT_INST_STOP, 1, 0)
|
||||
TP_INST_PR.Controls.Add(Me.PR_INST, 3, 0)
|
||||
TP_INST_PR.Controls.Add(Me.BTT_INST_OPEN, 2, 0)
|
||||
TP_INST_PR.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_INST_PR.Location = New System.Drawing.Point(0, 0)
|
||||
TP_INST_PR.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_INST_PR.Name = "TP_INST_PR"
|
||||
TP_INST_PR.RowCount = 1
|
||||
TP_INST_PR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_INST_PR.Size = New System.Drawing.Size(480, 29)
|
||||
TP_INST_PR.TabIndex = 0
|
||||
'
|
||||
'BTT_INST_START
|
||||
'
|
||||
Me.BTT_INST_START.BackgroundImage = Global.SCrawler.My.Resources.Resources.StartPic_01_Green_16
|
||||
Me.BTT_INST_START.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_INST_START.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_INST_START.Location = New System.Drawing.Point(3, 3)
|
||||
Me.BTT_INST_START.Name = "BTT_INST_START"
|
||||
Me.BTT_INST_START.Size = New System.Drawing.Size(24, 23)
|
||||
Me.BTT_INST_START.TabIndex = 0
|
||||
TT_MAIN.SetToolTip(Me.BTT_INST_START, "Start downloading saved Instagram posts")
|
||||
Me.BTT_INST_START.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_INST_STOP
|
||||
'
|
||||
Me.BTT_INST_STOP.BackgroundImage = Global.SCrawler.My.Resources.Resources.Delete
|
||||
Me.BTT_INST_STOP.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_INST_STOP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_INST_STOP.Enabled = False
|
||||
Me.BTT_INST_STOP.Location = New System.Drawing.Point(33, 3)
|
||||
Me.BTT_INST_STOP.Name = "BTT_INST_STOP"
|
||||
Me.BTT_INST_STOP.Size = New System.Drawing.Size(24, 23)
|
||||
Me.BTT_INST_STOP.TabIndex = 1
|
||||
TT_MAIN.SetToolTip(Me.BTT_INST_STOP, "Stop downloading saved Instagram posts")
|
||||
Me.BTT_INST_STOP.UseVisualStyleBackColor = True
|
||||
'
|
||||
'PR_INST
|
||||
'
|
||||
Me.PR_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.PR_INST.Location = New System.Drawing.Point(93, 3)
|
||||
Me.PR_INST.Name = "PR_INST"
|
||||
Me.PR_INST.Size = New System.Drawing.Size(384, 23)
|
||||
Me.PR_INST.TabIndex = 2
|
||||
'
|
||||
'BTT_INST_OPEN
|
||||
'
|
||||
Me.BTT_INST_OPEN.BackgroundImage = CType(resources.GetObject("BTT_INST_OPEN.BackgroundImage"), System.Drawing.Image)
|
||||
Me.BTT_INST_OPEN.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_INST_OPEN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_INST_OPEN.Location = New System.Drawing.Point(63, 3)
|
||||
Me.BTT_INST_OPEN.Name = "BTT_INST_OPEN"
|
||||
Me.BTT_INST_OPEN.Size = New System.Drawing.Size(24, 23)
|
||||
Me.BTT_INST_OPEN.TabIndex = 3
|
||||
Me.BTT_INST_OPEN.UseVisualStyleBackColor = True
|
||||
'
|
||||
'LBL_INST
|
||||
'
|
||||
Me.LBL_INST.AutoSize = True
|
||||
Me.LBL_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_INST.Location = New System.Drawing.Point(3, 29)
|
||||
Me.LBL_INST.Name = "LBL_INST"
|
||||
Me.LBL_INST.Size = New System.Drawing.Size(474, 30)
|
||||
Me.LBL_INST.TabIndex = 1
|
||||
Me.LBL_INST.Text = "Instagram"
|
||||
Me.LBL_INST.TextAlign = System.Drawing.ContentAlignment.TopCenter
|
||||
'
|
||||
'DownloadSavedPostsForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(484, 156)
|
||||
Me.Controls.Add(TP_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(500, 195)
|
||||
Me.MinimumSize = New System.Drawing.Size(500, 195)
|
||||
Me.Name = "DownloadSavedPostsForm"
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
Me.Text = "Saved posts"
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_BUTTONS.ResumeLayout(False)
|
||||
TP_REDDIT.ResumeLayout(False)
|
||||
TP_REDDIT.PerformLayout()
|
||||
TP_REDDIT_PR.ResumeLayout(False)
|
||||
TP_INST.ResumeLayout(False)
|
||||
TP_INST.PerformLayout()
|
||||
TP_INST_PR.ResumeLayout(False)
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents BTT_DOWN_ALL As Button
|
||||
Private WithEvents BTT_STOP_ALL As Button
|
||||
Private WithEvents BTT_REDDIT_START As Button
|
||||
Private WithEvents BTT_REDDIT_STOP As Button
|
||||
Private WithEvents PR_REDDIT As ProgressBar
|
||||
Private WithEvents LBL_REDDIT As Label
|
||||
Private WithEvents BTT_INST_START As Button
|
||||
Private WithEvents BTT_INST_STOP As Button
|
||||
Private WithEvents PR_INST As ProgressBar
|
||||
Private WithEvents LBL_INST As Label
|
||||
Private WithEvents BTT_REDDIT_OPEN As Button
|
||||
Private WithEvents BTT_INST_OPEN As Button
|
||||
End Class
|
||||
492
SCrawler/DownloadSavedPostsForm.resx
Normal file
492
SCrawler/DownloadSavedPostsForm.resx
Normal file
@@ -0,0 +1,492 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_REDDIT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_REDDIT_PR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_INST.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_INST_PR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="BTT_INST_OPEN.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TP_REDDIT_PR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="BTT_REDDIT_OPEN.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
|
||||
IACoJQAA7h4AABAQAAABACAAaAQAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4AAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vb/9vb2/wAAAAAAAAAAAAAAAAAAAAD29vb/9vb2/wAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v9kZGT/1NTU//b29v/29vb/1NTU/2Rk
|
||||
ZP/29vb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vb/QkJC/0JCQv+cnJz/nJyc/0JC
|
||||
Qv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC//b29v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv/29vb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vb/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC//b29v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9v9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv/29vb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA9vb2/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC//b29v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29v9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv/29vb/AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD29vb/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v8AAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP//AADzzwAA8A8AAPAPAADwDwAA8A8AAPAPAADwDwAA8A8AAPAPAADwDwAA8A8AAPAP
|
||||
AADwDwAA8A8AAP//AAAoAAAAGAAAADAAAAABACAAAAAAAAAJAADDDgAAww4AAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYV9vb2Z/b2
|
||||
9oT29vZn9vb2Ffb29gAAAAAAAAAAAPb29gD29vYV9vb2Z/b29oT29vZn9vb2Ffb29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYr9vb21Pf39//39/fb9/f3Tvf39yP29vYr9vb2K/f3
|
||||
9yP39/dO9/f32/f39//29vbU9vb2K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYr9vb21Pb29v/39/f49vb22/b29tP29vbU9vb21Pb29tP29vbb9/f3+Pb29v/29vbU9vb2K/b2
|
||||
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD5+fkr9/f31NHR0f+4uLj/4ODg//T0
|
||||
9P/5+fn/+fn5//T09P/g4OD/uLi4/9HR0f/39/fU+fn5K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD9/f0r9/f31Kmpqf9sbGz/qqqq/9XV1f/o6Oj/6Ojo/9XV1f+qqqr/bGxs/6mp
|
||||
qf/39/fU/f39K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31KGh
|
||||
of9ISEj/VVVV/4SEhP+tra3/ra2t/4SEhP9VVVX/SEhI/6Ghof/39/fU/v7+K/b29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/8/Pz//PDw8/1RUVP9tbW3/bW1t/1RU
|
||||
VP88PDz/Pz8//5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9BQUH/QUFB/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b2
|
||||
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/9BQUH/QUFB/0JC
|
||||
Qv9BQUH/QUFB/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+f
|
||||
n//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+f
|
||||
n/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9BQUH/QUFB/5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b2
|
||||
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/9BQUH/QUFB/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+f
|
||||
n//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+f
|
||||
n/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9BQUH/QUFB/5+fn//39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD+/v4r9/f31J+fn/9BQUH/QUFB/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/5+fn//39/fU/v7+K/b2
|
||||
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD+/v4r9/f31JycnP87Ozv/Ojo6/zw8
|
||||
PP88PDz/PDw8/zw8PP86Ojr/Ozs7/5ycnP/39/fU/v7+K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD9/f0r9/f31K6urv9gYGD/YGBg/2FhYf9hYWH/YWFh/2FhYf9gYGD/YGBg/66u
|
||||
rv/39/fU/f39K/b29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD39/cr9vb21Ojo
|
||||
6P/Y2Nj/2NjY/9jY2P/Y2Nj/2NjY/9jY2P/Y2Nj/2NjY/+jo6P/29vbU9/f3K/b29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYV9vb2Z/r6+oD///97////e////3v///97////e///
|
||||
/3v///97////e/r6+oD29vZn9vb2Ffb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA////APg8HwD4AB8A+AAfAPgAHwD4AB8A+AAfAPgAHwD4AB8A+AAfAPgA
|
||||
HwD4AB8A+AAfAPgAHwD4AB8A+AAfAPgAHwD4AB8A+AAfAPgAHwD4AB8A+AAfAPgAHwD///8AKAAAACAA
|
||||
AABAAAAAAQAgAAAAAAAAEAAAww4AAMMOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vYA9vb2APb29g/29vYu9vb2Pvb29j729vYu9vb2D/b29gD29vYAAAAAAAAAAAD29vYA9vb2APb2
|
||||
9g/29vYu9vb2Pvb29j729vYu9vb2D/b29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Lvb29pH29vbG9vb2xvb29pH29vYu9vb2APb29gAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Lvb29pH29vbG9vb2xvb29pH29vYu9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA9vb2APb29gD29vY+9vb2wff39//4+Pj/+Pj40Pj4+Gz4+Pg59vb2O/b2
|
||||
9j729vY+9vb2O/j4+Dn4+Phs+Pj40Pj4+P/39/f/9vb2wfb29j729vYA9vb2AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2APb29j729vbB9/f3//n5+f/5+fnw+Pj40Pf3
|
||||
98D29vbB9vb2wfb29sH29vbB9/f3wPj4+ND5+fnw+fn5//f39//29vbB9vb2Pvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA+Pj4Pvf398Ht7e3/29vb/9nZ
|
||||
2f/o6Oj/8/Pz//b29v/4+Pj/+Pj4//b29v/z8/P/6Ojo/9nZ2f/b29v/7e3t//f398H4+Pg+9vb2APb2
|
||||
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb29gD9/f0++fn5wdvb
|
||||
2/+ioqL/mpqa/8nJyf/o6Oj/9PT0//n5+f/5+fn/9PT0/+jo6P/Jycn/mpqa/6Kiov/b29v/+fn5wf39
|
||||
/T729vYA9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2AP//
|
||||
/z77+/vB0NDQ/35+fv9paWn/l5eX/76+vv/X19f/5OTk/+Tk5P/X19f/vr6+/5eXl/9paWn/fn5+/9DQ
|
||||
0P/7+/vB////Pvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA////Pvv7+8HNzc3/c3Nz/0pKSv9ZWVn/eHh4/6Ghof+3t7f/t7e3/6Ghof94eHj/WVlZ/0pK
|
||||
Sv9zc3P/zc3N//v7+8H///8+9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA9vb2APb29gD///8+/Pz8wcvLy/9vb2//Ozs7/zs7O/9PT0//c3Nz/4eHh/+Hh4f/c3Nz/09P
|
||||
T/87Ozv/Ozs7/29vb//Ly8v//Pz8wf///z729vYA9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD29vYA9vb2AP///z78/PzBy8vL/29vb/89PT3/PT09/0VFRf9RUVH/V1dX/1dX
|
||||
V/9RUVH/RUVF/z09Pf89PT3/b29v/8vLy//8/PzB////Pvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA////Pvz8/MHMzMz/b29v/z4+Pv8/Pz//QUFB/0BA
|
||||
QP9AQED/QEBA/0BAQP9BQUH/Pz8//z4+Pv9vb2//zMzM//z8/MH///8+9vb2APb29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb29gD///8+/Pz8wczMzP9vb2//Pj4+/z8/
|
||||
P/9CQkL/QUFB/0FBQf9BQUH/QUFB/0JCQv8/Pz//Pj4+/29vb//MzMz//Pz8wf///z729vYA9vb2AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2AP///z78/PzBzMzM/29v
|
||||
b/8+Pj7/Pz8//0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z8/P/8+Pj7/b29v/8zMzP/8/PzB////Pvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA////Pvz8
|
||||
/MHMzMz/b29v/z4+Pv8/Pz//QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/Pz8//z4+Pv9vb2//zMzM//z8
|
||||
/MH///8+9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb2
|
||||
9gD///8+/Pz8wczMzP9vb2//Pj4+/z8/P/9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv8/Pz//Pj4+/29v
|
||||
b//MzMz//Pz8wf///z729vYA9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vYA9vb2AP///z78/PzBzMzM/29vb/8+Pj7/Pz8//0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z8/
|
||||
P/8+Pj7/b29v/8zMzP/8/PzB////Pvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA////Pvz8/MHMzMz/b29v/z4+Pv8/Pz//QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/Pz8//z4+Pv9vb2//zMzM//z8/MH///8+9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA9vb2APb29gD///8+/Pz8wczMzP9vb2//Pj4+/z8/P/9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv8/Pz//Pj4+/29vb//MzMz//Pz8wf///z729vYA9vb2AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2AP///z78/PzBzMzM/29vb/8+Pj7/Pz8//0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/z8/P/8+Pj7/b29v/8zMzP/8/PzB////Pvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA////Pvz8/MHMzMz/b29v/z4+
|
||||
Pv8/Pz//QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/Pz8//z4+Pv9vb2//zMzM//z8/MH///8+9vb2APb2
|
||||
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb29gD///8+/Pz8wczM
|
||||
zP9vb2//Pj4+/z8/P/9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv8/Pz//Pj4+/29vb//MzMz//Pz8wf//
|
||||
/z729vYA9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2AP//
|
||||
/z78/PzBzMzM/29vb/8+Pj7/Pz8//0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z8/P/8+Pj7/b29v/8zM
|
||||
zP/8/PzB////Pvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA////Pvz8/MHMzMz/b29v/z4+Pv8/Pz//QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/Pz8//z4+
|
||||
Pv9vb2//zMzM//z8/MH///8+9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA9vb2APb29gD///8+/Pz8wczMzP9vb2//Pj4+/z8/P/9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv8/Pz//Pj4+/29vb//MzMz//Pz8wf///z729vYA9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD29vYA9vb2AP///z78/PzBy8vL/21tbf87Ozv/PT09/z8/P/8/Pz//Pz8//z8/
|
||||
P/8/Pz//Pz8//z09Pf87Ozv/bW1t/8vLy//8/PzB////Pvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA////Pvz8/MHLy8v/bGxs/zk5Of87Ozv/Pj4+/z4+
|
||||
Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Ozs7/zk5Of9sbGz/y8vL//z8/MH///8+9vb2APb29gAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb29gD+/v4++vr6wdbW1v+RkZH/bGxs/21t
|
||||
bf9vb2//b29v/29vb/9vb2//b29v/29vb/9tbW3/bGxs/5GRkf/W1tb/+vr6wf7+/j729vYA9vb2AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2APn5+T739/fB7Ozs/9bW
|
||||
1v/Ly8v/y8vL/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8vLy//Ly8v/1tbW/+zs7P/39/fB+fn5Pvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Lvb2
|
||||
9pH39/fD+vr6wfz8/L/8/Py//Pz8v/z8/L/8/Py//Pz8v/z8/L/8/Py//Pz8v/z8/L/6+vrB9/f3w/b2
|
||||
9pH29vYu9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb2
|
||||
9gD19fUP9vb2Lvj4+D79/f09////PP///zz///88////PP///zz///88////PP///zz///88////PP39
|
||||
/T34+Pg+9vb2LvX19Q/29vYA9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gfgf/4H
|
||||
4H/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//gAAf/4A
|
||||
AH/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//////ygA
|
||||
AAAwAAAAYAAAAAEAIAAAAAAAACQAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Afb29gX29vYK9vb2Dvb29hD29vYQ9vb2Dvb2
|
||||
9gr29vYF9vb2Afb29gD29vYAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Afb29gX29vYK9vb2Dvb2
|
||||
9hD29vYQ9vb2Dvb29gr29vYF9vb2Afb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2BPb29hr29vY29vb2S/b2
|
||||
9lT29vZU9vb2S/b29jb29vYa9vb2BPb29gD29vYAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2BPb2
|
||||
9hr29vY29vb2S/b29lT29vZU9vb2S/b29jb29vYa9vb2BPb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Cfb2
|
||||
9jf29vZy9vb2n/b29rL29vay9vb2n/b29nL29vY39vb2Cfb29gD29vYAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Cfb29jf29vZy9vb2n/b29rL29vay9vb2n/b29nL29vY39vb2Cfb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dfb29k729vaj9vb24/b29v729vb+9vb25Pb29qj29vZX9vb2G/b29gf29vYJ9vb2Dvb2
|
||||
9g729vYO9vb2Dvb29gn29vYH9vb2G/b29lf29vao9vb25Pb29v729vb+9vb24/b29qP29vZO9vb2Dfb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dvb29lL29vat9vb28ff39//4+Pj/+fn59fn5+cf5+fmK+Pj4XPf3
|
||||
90339/dO9vb2Uvb29lL29vZS9vb2Uvf390739/dN+Pj4XPn5+Yr5+fnH+fn59fj4+P/39/f/9vb28fb2
|
||||
9q329vZS9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dvb29lL29vat9vb28fj4+P/5+fn/+vr6+vr6
|
||||
+uT5+fnH+Pj4sff396r29var9vb2rfb29q329vat9vb2rfb29qv39/eq+Pj4sfn5+cf6+vrk+vr6+vn5
|
||||
+f/4+Pj/9vb28fb29q329vZS9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dvf391L29vat9vb28fPz
|
||||
8//w8PD/7+/v/u/v7/ry8vL19PT08vX19fD29vbx9vb28fb29vH29vbx9vb28fb29vH19fXw9PT08vLy
|
||||
8vXv7+/67+/v/vDw8P/z8/P/9vb28fb29q339/dS9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dvn5
|
||||
+VL4+Pit8/Pz8efn5//W1tb/zMzM/9LS0v/h4eH/7e3t//Pz8//29vb/9/f3//j4+P/4+Pj/9/f3//b2
|
||||
9v/z8/P/7e3t/+Hh4f/S0tL/zMzM/9bW1v/n5+f/8/Pz8fj4+K35+flS9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv39/VL7+/ut8PDw8dbW1v+zs7P/np6e/6qqqv/Hx8f/4eHh/+7u7v/09PT/+Pj4//r6
|
||||
+v/6+vr/+Pj4//T09P/u7u7/4eHh/8fHx/+qqqr/np6e/7Ozs//W1tb/8PDw8fv7+639/f1S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L9/f2t7u7u8cjIyP+Wlpb/eHh4/4WFhf+pqan/ysrK/9zc
|
||||
3P/o6Oj/7+/v//Pz8//z8/P/7+/v/+jo6P/c3Nz/ysrK/6mpqf+FhYX/eHh4/5aWlv/IyMj/7u7u8f39
|
||||
/a3///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L+/v6t7Ozs8cLCwv+IiIj/YmJi/2dn
|
||||
Z/+FhYX/oqKi/7i4uP/Ly8v/2NjY/97e3v/e3t7/2NjY/8vLy/+4uLj/oqKi/4WFhf9nZ2f/YmJi/4iI
|
||||
iP/CwsL/7Ozs8f7+/q3///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L+/v6t7Ozs8b+/
|
||||
v/+Dg4P/VVVV/09PT/9dXV3/cnJy/4qKiv+kpKT/uLi4/8DAwP/AwMD/uLi4/6SkpP+Kior/cnJy/11d
|
||||
Xf9PT0//VVVV/4ODg/+/v7//7Ozs8f7+/q3///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv//
|
||||
/1L///+t7Ozs8b6+vv+AgID/Tk5O/z4+Pv9BQUH/Tk5O/2VlZf+CgoL/l5eX/6Ghof+hoaH/l5eX/4KC
|
||||
gv9lZWX/Tk5O/0FBQf8+Pj7/Tk5O/4CAgP++vr7/7Ozs8f///63///9S9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv///1L///+t6+vr8b29vf9+fn7/S0tL/zg4OP84ODj/QUFB/1FRUf9oaGj/eHh4/39/
|
||||
f/9/f3//eHh4/2hoaP9RUVH/QUFB/zg4OP84ODj/S0tL/35+fv+9vb3/6+vr8f///63///9S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9+fn7/S0tL/zo6Ov86Ojr/QUFB/0hI
|
||||
SP9TU1P/W1tb/19fX/9fX1//W1tb/1NTU/9ISEj/QUFB/zo6Ov86Ojr/S0tL/35+fv++vr7/6+vr8f//
|
||||
/63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8
|
||||
PP8+Pj7/QkJC/0RERP9FRUX/R0dH/0dHR/9HR0f/R0dH/0VFRf9ERET/QkJC/z4+Pv88PDz/TExM/39/
|
||||
f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+
|
||||
vv9/f3//TExM/zw8PP8+Pj7/QkJC/0FBQf9AQED/Pz8//z8/P/8/Pz//Pz8//0BAQP9BQUH/QkJC/z4+
|
||||
Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv//
|
||||
/1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0FBQf9BQUH/QEBA/0BAQP9AQED/QEBA/0FB
|
||||
Qf9BQUH/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f//
|
||||
/63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8
|
||||
PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/
|
||||
f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+
|
||||
vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+
|
||||
Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv//
|
||||
/1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f//
|
||||
/63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8
|
||||
PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/
|
||||
f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+
|
||||
vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+
|
||||
Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv//
|
||||
/1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f//
|
||||
/63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8
|
||||
PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/
|
||||
f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+
|
||||
vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+
|
||||
Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv//
|
||||
/1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/f/++vr7/6+vr8f//
|
||||
/63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+vv9/f3//TExM/zw8
|
||||
PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+Pv88PDz/TExM/39/
|
||||
f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L///+t6+vr8b6+
|
||||
vv9/f3//TExM/zw8PP8+Pj7/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/z4+
|
||||
Pv88PDz/TExM/39/f/++vr7/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv//
|
||||
/1L///+t6+vr8by8vP98fHz/SEhI/zg4OP86Ojr/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+
|
||||
Pv8+Pj7/Pj4+/zo6Ov84ODj/SEhI/3x8fP+8vLz/6+vr8f///63///9S9vb2Dvb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2Dv///1L///+t6+vr8by8vP97e3v/RkZG/zY2Nv84ODj/PDw8/zw8PP88PDz/PDw8/zw8
|
||||
PP88PDz/PDw8/zw8PP88PDz/PDw8/zg4OP82Njb/RkZG/3t7e/+8vLz/6+vr8f///63///9S9vb2Dvb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2Dv///1L+/v6t7Ozs8cHBwf+FhYX/VVVV/0ZGRv9ISEj/TExM/0xM
|
||||
TP9MTEz/TExM/0xMTP9MTEz/TExM/0xMTP9MTEz/TExM/0hISP9GRkb/VVVV/4WFhf/BwcH/7Ozs8f7+
|
||||
/q3///9S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dv7+/lL8/Pyt7+/v8dHR0f+np6f/hYWF/3t7
|
||||
e/98fHz/f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//3x8fP97e3v/hYWF/6en
|
||||
p//R0dH/7+/v8fz8/K3+/v5S9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dvr6+lL5+fmt8/Pz8eTk
|
||||
5P/R0dH/wcHB/7y8vP+8vLz/vr6+/76+vv++vr7/vr6+/76+vv++vr7/vr6+/76+vv++vr7/vr6+/7y8
|
||||
vP+8vLz/wcHB/9HR0f/k5OT/8/Pz8fn5+a36+vpS9vb2Dvb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Dff3
|
||||
90739/ej9fX14/Pz8/nv7+/27Ozs8evr6/Hr6+vx6+vr8evr6/Hr6+vx6+vr8evr6/Hr6+vx6+vr8evr
|
||||
6/Hr6+vx6+vr8evr6/Hr6+vx7Ozs8e/v7/bz8/P59fX14/f396P39/dO9vb2Dfb29gD29vYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9gD29vYA9vb2CfX19Tf29vZy9/f3n/n5+a78/Pyt/v7+qf///6n///+p////qf///6n///+p////qf//
|
||||
/6n///+p////qf///6n///+p////qf///6n///+p/v7+qfz8/K35+fmu9/f3n/b29nL19fU39vb2Cfb2
|
||||
9gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29gD29vYA9vb2BPX19Rr29vY29/f3S/n5+VL8/PxS////UP///1D///9Q////UP//
|
||||
/1D///9Q////UP///1D///9Q////UP///1D///9Q////UP///1D///9Q////UPz8/FL5+flS9/f3S/b2
|
||||
9jb19fUa9vb2BPb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29gD29vYA9vb2Afb29gX29vYK9vb2Dvb29g/29vYP9vb2D/b2
|
||||
9g/29vYP9vb2D/b29g/29vYP9vb2D/b29g/29vYP9vb2D/b29g/29vYP9vb2D/b29g/29vYP9vb2D/b2
|
||||
9g/29vYP9vb2Dvb29gr29vYF9vb2Afb29gD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///////8AAP/AD/AD/wAA/8AP8AP/AAD/wA/wA/8AAP/AAAAD/wAA/8AAAAP/
|
||||
AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/A
|
||||
AAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/
|
||||
AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/A
|
||||
AAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/
|
||||
AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/A
|
||||
AAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA////////AAAoAAAAEAAAACAAAAABACAAAAAAAAAE
|
||||
AADDDgAAww4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vb/9vb2/wAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v9kZGT/1NTU//b2
|
||||
9v/29vb/1NTU/2RkZP/29vb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vb/QkJC/0JC
|
||||
Qv+cnJz/nJyc/0JCQv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC//b29v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
|
||||
9v9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv/29vb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA9vb2/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC//b29v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPb29v9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv/29vb/AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD29vb/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/9vb2/wAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA9vb2/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC//b29v8AAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv/29vb/AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vb/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/9vb2/wAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AADzzwAA8A8AAPAPAADwDwAA8A8AAPAPAADwDwAA8A8AAPAP
|
||||
AADwDwAA8A8AAPAPAADwDwAA8A8AAP//AAA=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
157
SCrawler/DownloadSavedPostsForm.vb
Normal file
157
SCrawler/DownloadSavedPostsForm.vb
Normal file
@@ -0,0 +1,157 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Imports System.Threading
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API
|
||||
Imports Job = SCrawler.TDownloader.Job
|
||||
Friend Class DownloadSavedPostsForm
|
||||
Friend Event OnDownloadDone(ByVal Message As String)
|
||||
Private MyView As FormsView
|
||||
Private ReadOnly ProgressReddit As MyProgress
|
||||
Private ReadOnly ProgressInstgram As MyProgress
|
||||
Private JobReddit As Job
|
||||
Private JobInstagram As Job
|
||||
Friend ReadOnly Property Working As Boolean
|
||||
Get
|
||||
Return JobReddit Or JobInstagram
|
||||
End Get
|
||||
End Property
|
||||
#Region "Start and Stop functions"
|
||||
Friend Overloads Sub [Stop]()
|
||||
[Stop](Sites.Reddit)
|
||||
[Stop](Sites.Instagram)
|
||||
End Sub
|
||||
Private Overloads Sub [Stop](ByVal Site As Sites)
|
||||
Select Case Site
|
||||
Case Sites.Reddit : If JobReddit Then JobReddit.Stop()
|
||||
Case Sites.Instagram : If JobInstagram Then JobInstagram.Stop()
|
||||
End Select
|
||||
End Sub
|
||||
Private Overloads Sub [Start]()
|
||||
Start(Sites.Reddit)
|
||||
Start(Sites.Instagram)
|
||||
End Sub
|
||||
Private Overloads Sub [Start](ByVal Site As Sites)
|
||||
Select Case Site
|
||||
Case Sites.Reddit : If Not JobReddit Then JobReddit.Start(New ThreadStart(Sub() DownloadData(Sites.Reddit)))
|
||||
Case Sites.Instagram
|
||||
If Not JobInstagram Then
|
||||
If Not Downloader.Working(Sites.Instagram) Then
|
||||
Downloader.InstagramSavedPostsDownloading = True
|
||||
JobInstagram.Start(New ThreadStart(Sub() DownloadData(Sites.Instagram)))
|
||||
Else
|
||||
MsgBoxE({$"Downloading Instagram profiles still works.{vbCr}Wait for this to be done before starting.{vbCr}Operation canceled",
|
||||
"Instagram saved posts"}, MsgBoxStyle.Critical)
|
||||
End If
|
||||
End If
|
||||
End Select
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Form functions"
|
||||
Friend Sub New()
|
||||
InitializeComponent()
|
||||
ProgressReddit = New MyProgress(PR_REDDIT, LBL_REDDIT)
|
||||
ProgressInstgram = New MyProgress(PR_INST, LBL_INST)
|
||||
JobReddit = New Job(ProgressReddit) With {.Site = Sites.Reddit}
|
||||
JobInstagram = New Job(ProgressInstgram) With {.Site = Sites.Instagram}
|
||||
End Sub
|
||||
Private Sub DownloadSavedPostsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
MyView = New FormsView(Me) With {.LocationOnly = True}
|
||||
MyView.ImportFromXML(Settings.Design)
|
||||
MyView.SetMeSize()
|
||||
End Sub
|
||||
Private Sub DownloadSavedPostsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||
e.Cancel = True
|
||||
Hide()
|
||||
End Sub
|
||||
Private Sub DownloadSavedPostsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
[Stop]()
|
||||
MyView.Dispose(Settings.Design)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Controls"
|
||||
Private Sub BTT_DOWN_ALL_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_ALL.Click
|
||||
Start()
|
||||
End Sub
|
||||
Private Sub BTT_STOP_ALL_Click(sender As Object, e As EventArgs) Handles BTT_STOP_ALL.Click
|
||||
[Stop]()
|
||||
End Sub
|
||||
#Region "Reddit"
|
||||
Private Sub BTT_REDDIT_START_Click(sender As Object, e As EventArgs) Handles BTT_REDDIT_START.Click
|
||||
Start(Sites.Reddit)
|
||||
End Sub
|
||||
Private Sub BTT_REDDIT_STOP_Click(sender As Object, e As EventArgs) Handles BTT_REDDIT_STOP.Click
|
||||
[Stop](Sites.Reddit)
|
||||
End Sub
|
||||
Private Sub BTT_REDDIT_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_REDDIT_OPEN.Click
|
||||
OpenPath(Reddit.ProfileSaved.DataPath)
|
||||
End Sub
|
||||
Private Sub LBL_REDDIT_DoubleClick(sender As Object, e As EventArgs) Handles LBL_REDDIT.DoubleClick
|
||||
OpenPath(Reddit.ProfileSaved.DataPath)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Instagram"
|
||||
Private Sub BTT_INST_START_Click(sender As Object, e As EventArgs) Handles BTT_INST_START.Click
|
||||
Start(Sites.Instagram)
|
||||
End Sub
|
||||
Private Sub BTT_INST_STOP_Click(sender As Object, e As EventArgs) Handles BTT_INST_STOP.Click
|
||||
[Stop](Sites.Instagram)
|
||||
End Sub
|
||||
Private Sub BTT_INST_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_INST_OPEN.Click
|
||||
OpenPath(Instagram.ProfileSaved.DataPath)
|
||||
End Sub
|
||||
Private Sub LBL_INST_DoubleClick(sender As Object, e As EventArgs) Handles LBL_INST.DoubleClick
|
||||
OpenPath(Instagram.ProfileSaved.DataPath)
|
||||
End Sub
|
||||
#End Region
|
||||
#End Region
|
||||
Private Sub DownloadData(ByVal Site As Sites)
|
||||
Dim btte As Action(Of Button, Boolean) = Sub(b, e) If b.InvokeRequired Then b.Invoke(Sub() b.Enabled = e) Else b.Enabled = e
|
||||
Try
|
||||
Select Case Site
|
||||
Case Sites.Reddit
|
||||
btte(BTT_REDDIT_START, False)
|
||||
btte(BTT_REDDIT_STOP, True)
|
||||
JobReddit.Progress.InformationTemporary = "Reddit downloading started"
|
||||
JobReddit.Start()
|
||||
Reddit.ProfileSaved.Download(JobReddit.Progress, JobReddit)
|
||||
Case Sites.Instagram
|
||||
btte(BTT_INST_START, False)
|
||||
btte(BTT_INST_STOP, True)
|
||||
JobInstagram.Progress.InformationTemporary = "Instagram downloading started"
|
||||
JobInstagram.Start()
|
||||
Instagram.ProfileSaved.Download(JobInstagram.Progress, JobInstagram)
|
||||
End Select
|
||||
RaiseEvent OnDownloadDone($"Downloading saved {Site} posts is completed")
|
||||
Catch ex As Exception
|
||||
Select Case Site
|
||||
Case Sites.Reddit : JobReddit.Progress.InformationTemporary = "Reddit downloading error"
|
||||
Case Sites.Instagram : JobInstagram.Progress.InformationTemporary = "Instagram downloading error"
|
||||
End Select
|
||||
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Site} saved posts downloading error", "Saved posts"})
|
||||
Finally
|
||||
Select Case Site
|
||||
Case Sites.Reddit
|
||||
JobReddit.Stopped()
|
||||
btte(BTT_REDDIT_START, True)
|
||||
btte(BTT_REDDIT_STOP, False)
|
||||
Case Sites.Instagram
|
||||
JobInstagram.Stopped()
|
||||
btte(BTT_INST_START, True)
|
||||
btte(BTT_INST_STOP, False)
|
||||
Downloader.InstagramSavedPostsDownloading = False
|
||||
End Select
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub OpenPath(ByVal f As SFile)
|
||||
If f.Exists(SFO.Path, False) Then f.Open(SFO.Path)
|
||||
End Sub
|
||||
End Class
|
||||
25
SCrawler/DownloadedInfoForm.Designer.vb
generated
25
SCrawler/DownloadedInfoForm.Designer.vb
generated
@@ -14,6 +14,7 @@ Partial Friend Class DownloadedInfoForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadedInfoForm))
|
||||
Dim SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
|
||||
Me.MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
|
||||
Me.MENU_VIEW_SESSION = New System.Windows.Forms.ToolStripMenuItem()
|
||||
@@ -21,13 +22,15 @@ Partial Friend Class DownloadedInfoForm : Inherits System.Windows.Forms.Form
|
||||
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
|
||||
Me.ToolbarBOTTOM = New System.Windows.Forms.StatusStrip()
|
||||
Me.LIST_DOWN = New System.Windows.Forms.ListBox()
|
||||
Me.BTT_CLEAR = New System.Windows.Forms.ToolStripButton()
|
||||
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
Me.ToolbarTOP.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'ToolbarTOP
|
||||
'
|
||||
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW, Me.BTT_REFRESH})
|
||||
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW, Me.BTT_REFRESH, SEP_1, Me.BTT_CLEAR})
|
||||
Me.ToolbarTOP.Location = New System.Drawing.Point(0, 0)
|
||||
Me.ToolbarTOP.Name = "ToolbarTOP"
|
||||
Me.ToolbarTOP.Size = New System.Drawing.Size(554, 25)
|
||||
@@ -48,7 +51,7 @@ Partial Friend Class DownloadedInfoForm : Inherits System.Windows.Forms.Form
|
||||
'
|
||||
Me.MENU_VIEW_SESSION.AutoToolTip = True
|
||||
Me.MENU_VIEW_SESSION.Name = "MENU_VIEW_SESSION"
|
||||
Me.MENU_VIEW_SESSION.Size = New System.Drawing.Size(180, 22)
|
||||
Me.MENU_VIEW_SESSION.Size = New System.Drawing.Size(113, 22)
|
||||
Me.MENU_VIEW_SESSION.Text = "Session"
|
||||
Me.MENU_VIEW_SESSION.ToolTipText = "Show downloaded users by this session"
|
||||
'
|
||||
@@ -56,7 +59,7 @@ Partial Friend Class DownloadedInfoForm : Inherits System.Windows.Forms.Form
|
||||
'
|
||||
Me.MENU_VIEW_ALL.AutoToolTip = True
|
||||
Me.MENU_VIEW_ALL.Name = "MENU_VIEW_ALL"
|
||||
Me.MENU_VIEW_ALL.Size = New System.Drawing.Size(180, 22)
|
||||
Me.MENU_VIEW_ALL.Size = New System.Drawing.Size(113, 22)
|
||||
Me.MENU_VIEW_ALL.Text = "All"
|
||||
Me.MENU_VIEW_ALL.ToolTipText = "Show all users (sorted by latest download)"
|
||||
'
|
||||
@@ -85,6 +88,21 @@ Partial Friend Class DownloadedInfoForm : Inherits System.Windows.Forms.Form
|
||||
Me.LIST_DOWN.Size = New System.Drawing.Size(554, 364)
|
||||
Me.LIST_DOWN.TabIndex = 2
|
||||
'
|
||||
'SEP_1
|
||||
'
|
||||
SEP_1.Name = "SEP_1"
|
||||
SEP_1.Size = New System.Drawing.Size(6, 25)
|
||||
'
|
||||
'BTT_CLEAR
|
||||
'
|
||||
Me.BTT_CLEAR.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
||||
Me.BTT_CLEAR.Image = CType(resources.GetObject("BTT_CLEAR.Image"), System.Drawing.Image)
|
||||
Me.BTT_CLEAR.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||
Me.BTT_CLEAR.Name = "BTT_CLEAR"
|
||||
Me.BTT_CLEAR.Size = New System.Drawing.Size(38, 22)
|
||||
Me.BTT_CLEAR.Text = "Clear"
|
||||
Me.BTT_CLEAR.ToolTipText = "Clear info list"
|
||||
'
|
||||
'DownloadedInfoForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
@@ -112,4 +130,5 @@ Partial Friend Class DownloadedInfoForm : Inherits System.Windows.Forms.Form
|
||||
Private WithEvents BTT_REFRESH As ToolStripButton
|
||||
Private WithEvents ToolbarBOTTOM As StatusStrip
|
||||
Private WithEvents LIST_DOWN As ListBox
|
||||
Private WithEvents BTT_CLEAR As ToolStripButton
|
||||
End Class
|
||||
@@ -134,6 +134,24 @@
|
||||
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<data name="BTT_CLEAR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
|
||||
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
|
||||
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
|
||||
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
|
||||
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
|
||||
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
|
||||
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
|
||||
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="ToolbarBOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
|
||||
@@ -45,6 +45,7 @@ Friend Class DownloadedInfoForm
|
||||
MyView.ImportFromXML(Settings.Design)
|
||||
MyView.SetMeSize()
|
||||
End If
|
||||
BTT_CLEAR.Visible = ViewMode = ViewModes.Session
|
||||
RefillList()
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
@@ -104,17 +105,25 @@ Friend Class DownloadedInfoForm
|
||||
MENU_VIEW_SESSION.Checked = True
|
||||
MENU_VIEW_ALL.Checked = False
|
||||
ViewMode = ViewModes.Session
|
||||
BTT_CLEAR.Visible = True
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub MENU_VIEW_ALL_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_ALL.Click
|
||||
MENU_VIEW_SESSION.Checked = False
|
||||
MENU_VIEW_ALL.Checked = True
|
||||
ViewMode = ViewModes.All
|
||||
BTT_CLEAR.Visible = False
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub BTT_REFRESH_Click(sender As Object, e As EventArgs) Handles BTT_REFRESH.Click
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub BTT_CLEAR_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR.Click
|
||||
If LIST_DOWN.Items.Count > 0 Then
|
||||
Downloader.Downloaded.Clear()
|
||||
RefillList()
|
||||
End If
|
||||
End Sub
|
||||
Private _LatestSelected As Integer = -1
|
||||
Private Sub LIST_DOWN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_DOWN.SelectedIndexChanged
|
||||
_LatestSelected = LIST_DOWN.SelectedIndex
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Controls.Base
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
@@ -28,50 +27,40 @@ Namespace Editors
|
||||
Try
|
||||
With MyDefs
|
||||
.MyViewInitialize(Me, Settings.Design)
|
||||
.MyOkCancel = New OkCancelToolbar(Me, Me, CONTAINER_MAIN.BottomToolStripPanel)
|
||||
.MyOkCancel.AddThisToolbar()
|
||||
.AddOkCancelToolbar()
|
||||
.DelegateClosingChecker()
|
||||
Collections.ListAddList((From c In Settings.Users Where c.IsCollection Select c.CollectionName), LAP.NotContainsOnly, EDP.ThrowException)
|
||||
If Collections.ListExists Then CMB_COLLECTIONS.Items.AddRange(From c In Collections Select New Controls.Base.ListItem(c))
|
||||
If Collections.ListExists Then Collections.Sort() : CMB_COLLECTIONS.Items.AddRange(From c In Collections Select New ListItem(c))
|
||||
If Not Collection.IsEmptyString And Collections.Contains(Collection) Then CMB_COLLECTIONS.SelectedIndex = Collections.IndexOf(Collection)
|
||||
End With
|
||||
Catch ex As Exception
|
||||
MyDefs.InvokeLoaderError(ex)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub CollectionEditorForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||
If Not BeforeCloseChecker(MyDefs.ChangesDetected) Then
|
||||
e.Cancel = True
|
||||
Else
|
||||
Collections.Clear()
|
||||
MyDefs.Dispose()
|
||||
End If
|
||||
Private Sub CollectionEditorForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
Collections.Clear()
|
||||
End Sub
|
||||
Private Sub CollectionEditorForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||
If e.KeyCode = Keys.Insert Then
|
||||
AddNewCollection()
|
||||
e.Handled = True
|
||||
Else
|
||||
e.Handled = False
|
||||
End If
|
||||
If e.KeyCode = Keys.Insert Then AddNewCollection() : e.Handled = True Else e.Handled = False
|
||||
End Sub
|
||||
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
|
||||
If CMB_COLLECTIONS.SelectedIndex >= 0 Then
|
||||
Collection = CMB_COLLECTIONS.Value.ToString
|
||||
MyDefs.ChangesDetected = False
|
||||
DialogResult = DialogResult.OK
|
||||
Close()
|
||||
MyDefs.CloseForm()
|
||||
Else
|
||||
MsgBoxE("Collection does not selected", MsgBoxStyle.Exclamation)
|
||||
MsgBoxE("Collection not selected", MsgBoxStyle.Exclamation)
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ToolbarBttCancel() Implements IOkCancelToolbar.ToolbarBttCancel
|
||||
MyDefs.ChangesDetected = False
|
||||
DialogResult = DialogResult.Cancel
|
||||
Close()
|
||||
MyDefs.CloseForm(DialogResult.Cancel)
|
||||
End Sub
|
||||
Private Sub CMB_COLLECTIONS_ActionOnButtonClick(ByVal Sender As ActionButton) Handles CMB_COLLECTIONS.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ActionButton.DefaultButtons.Add Then AddNewCollection()
|
||||
End Sub
|
||||
Private Sub CMB_COLLECTIONS_ActionOnListDoubleClick(ByVal _Item As ListViewItem) Handles CMB_COLLECTIONS.ActionOnListDoubleClick
|
||||
_Item.Selected = True
|
||||
ToolbarBttOK()
|
||||
End Sub
|
||||
Private Sub AddNewCollection()
|
||||
Dim c$ = InputBoxE("Enter new collection name:", "Collection name")
|
||||
If Not c.IsEmptyString Then
|
||||
|
||||
1054
SCrawler/Editors/GlobalSettingsForm.Designer.vb
generated
1054
SCrawler/Editors/GlobalSettingsForm.Designer.vb
generated
File diff suppressed because it is too large
Load Diff
@@ -214,9 +214,6 @@ If checked, videos will be stored in separate folder; otherwise, videos will be
|
||||
<metadata name="TP_CHANNELS_IMGS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TAB_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TAB_BASIS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
@@ -235,18 +232,9 @@ If checked, videos will be stored in separate folder; otherwise, videos will be
|
||||
<metadata name="TAB_DEFS_REDDIT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_REDDIT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TAB_DEFS_TWITTER.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_TWITTER.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_INSTAGRAM.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAA8AAAAQAAEABAAwOgAA9gAAADAwEAABAAQAaAYAACg7AAAgIBAAAQAEAOgCAACQQQAAGBgQAAEA
|
||||
|
||||
@@ -12,6 +12,7 @@ Imports PersonalUtilities.Forms.Toolbars
|
||||
Namespace Editors
|
||||
Friend Class GlobalSettingsForm : Implements IOkCancelToolbar
|
||||
Private ReadOnly MyDefs As DefaultFormProps(Of FieldsChecker)
|
||||
#Region "Checkers declarations"
|
||||
Private Class SavedPostsChecker : Implements ICustomProvider
|
||||
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||
@@ -25,6 +26,24 @@ Namespace Editors
|
||||
Throw New NotImplementedException()
|
||||
End Function
|
||||
End Class
|
||||
Private Class InstaTimersChecker : Implements ICustomProvider
|
||||
Private ReadOnly _LowestValue As Integer
|
||||
Friend Sub New(ByVal LowestValue As Integer)
|
||||
_LowestValue = LowestValue
|
||||
End Sub
|
||||
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||
If ACheck(Of Integer)(Value) AndAlso CInt(Value) >= _LowestValue Then
|
||||
Return Value
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Function
|
||||
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
|
||||
Throw New NotImplementedException()
|
||||
End Function
|
||||
End Class
|
||||
#End Region
|
||||
Friend Sub New()
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormProps(Of FieldsChecker)
|
||||
@@ -65,32 +84,39 @@ Namespace Editors
|
||||
CH_FILE_TIME.Checked = .FileAddTimeToFileName
|
||||
OPT_FILE_DATE_START.Checked = Not .FileDateTimePositionEnd
|
||||
OPT_FILE_DATE_END.Checked = .FileDateTimePositionEnd
|
||||
'Other program settings
|
||||
CH_EXIT_CONFIRM.Checked = .ExitConfirm
|
||||
CH_CLOSE_TO_TRAY.Checked = .CloseToTray
|
||||
CH_SHOW_NOTIFY.Checked = .ShowNotifications
|
||||
'Reddit
|
||||
With .Site(Sites.Reddit)
|
||||
SetChecker(CH_REDDIT_TEMP, .Temporary)
|
||||
SetChecker(CH_REDDIT_DOWN_IMG, .DownloadImages)
|
||||
SetChecker(CH_REDDIT_DOWN_VID, .DownloadVideos)
|
||||
SetChecker(DEFS_REDDIT, Sites.Reddit)
|
||||
TXT_REDDIT_SAVED_POSTS_USER.Text = .SavedPostsUserName
|
||||
End With
|
||||
'Twitter
|
||||
With .Site(Sites.Twitter)
|
||||
SetChecker(CH_TWITTER_TEMP, .Temporary)
|
||||
SetChecker(CH_TWITTER_DOWN_IMG, .DownloadImages)
|
||||
SetChecker(CH_TWITTER_DOWN_VID, .DownloadVideos)
|
||||
SetChecker(DEFS_TWITTER, Sites.Twitter)
|
||||
CH_TWITTER_USER_MEDIA.Checked = .GetUserMediaOnly
|
||||
End With
|
||||
'Instagram
|
||||
With .Site(Sites.Instagram)
|
||||
SetChecker(CH_INSTA_TEMP, .Temporary)
|
||||
SetChecker(CH_INSTA_DOWN_IMG, .DownloadImages)
|
||||
SetChecker(CH_INSTA_DOWN_VID, .DownloadVideos)
|
||||
SetChecker(DEFS_INST, Sites.Instagram)
|
||||
TXT_REQ_WAIT_TIMER.Text = .RequestsWaitTimer
|
||||
TXT_REQ_COUNT.Text = .RequestsWaitTimerTaskCount
|
||||
TXT_LIMIT_TIMER.Text = .SleepTimerOnPostsLimit
|
||||
TXT_INST_SAVED_POSTS_USER.Text = .SavedPostsUserName
|
||||
End With
|
||||
'RedGifs
|
||||
SetChecker(DEFS_REDGIFS, Sites.RedGifs)
|
||||
End With
|
||||
.MyFieldsChecker = New FieldsChecker
|
||||
With .MyFieldsChecker
|
||||
.AddControl(Of String)(TXT_GLOBAL_PATH, TXT_GLOBAL_PATH.CaptionText)
|
||||
.AddControl(Of String)(TXT_COLLECTIONS_PATH, TXT_COLLECTIONS_PATH.CaptionText)
|
||||
.AddControl(Of String)(TXT_REDDIT_SAVED_POSTS_USER, TXT_REDDIT_SAVED_POSTS_USER.CaptionText, True, New SavedPostsChecker)
|
||||
.AddControl(Of Integer)(TXT_REQ_WAIT_TIMER, TXT_REQ_WAIT_TIMER.CaptionText,, New InstaTimersChecker(100))
|
||||
.AddControl(Of Integer)(TXT_REQ_COUNT, TXT_REQ_COUNT.CaptionText,, New InstaTimersChecker(1))
|
||||
.AddControl(Of Integer)(TXT_LIMIT_TIMER, TXT_LIMIT_TIMER.CaptionText,, New InstaTimersChecker(10000))
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
.AppendDetectors()
|
||||
@@ -101,15 +127,30 @@ Namespace Editors
|
||||
MyDefs.InvokeLoaderError(ex)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub SetChecker(ByRef CH As CheckBox, ByVal Prop As XML.Base.XMLValue(Of Boolean))
|
||||
Private Overloads Sub SetChecker(ByRef CH As SiteDefaults, ByVal s As Sites)
|
||||
With Settings(s)
|
||||
SetChecker(CH.MyTemporary, .Temporary)
|
||||
SetChecker(CH.MyImagesDown, .DownloadImages)
|
||||
SetChecker(CH.MyVideosDown, .DownloadVideos)
|
||||
End With
|
||||
End Sub
|
||||
Private Overloads Sub SetChecker(ByRef State As CheckState, ByVal Prop As XML.Base.XMLValue(Of Boolean))
|
||||
If Prop.ValueF.Exists Then
|
||||
CH.Checked = Prop.Value
|
||||
State = If(Prop.Value, CheckState.Checked, CheckState.Unchecked)
|
||||
Else
|
||||
CH.CheckState = CheckState.Indeterminate
|
||||
State = CheckState.Indeterminate
|
||||
End If
|
||||
End Sub
|
||||
Private Sub SetPropByChecker(ByRef Prop As XML.Base.XMLValue(Of Boolean), ByRef CH As CheckBox)
|
||||
Select Case CH.CheckState
|
||||
Private Overloads Sub SetPropByChecker(ByRef CH As SiteDefaults, ByVal s As Sites)
|
||||
With Settings(s)
|
||||
SetPropByChecker(CH.MyTemporary, .Temporary)
|
||||
SetPropByChecker(CH.MyTemporary, .Temporary)
|
||||
SetPropByChecker(CH.MyImagesDown, .DownloadImages)
|
||||
SetPropByChecker(CH.MyVideosDown, .DownloadVideos)
|
||||
End With
|
||||
End Sub
|
||||
Private Overloads Sub SetPropByChecker(ByVal State As CheckState, ByRef Prop As XML.Base.XMLValue(Of Boolean))
|
||||
Select Case State
|
||||
Case CheckState.Checked : Prop.Value = True
|
||||
Case CheckState.Unchecked : Prop.Value = False
|
||||
Case CheckState.Indeterminate : Prop.ValueF = Nothing
|
||||
@@ -167,6 +208,10 @@ Namespace Editors
|
||||
.FromChannelDownloadTopUse.Value = TXT_CHANNEL_USER_POST_LIMIT.Checked
|
||||
.FromChannelCopyImageToUser.Value = CH_COPY_CHANNEL_USER_IMAGE.Checked
|
||||
.ChannelsDefaultTemporary.Value = CH_CHANNELS_USERS_TEMP.Checked
|
||||
'Other program settings
|
||||
.ExitConfirm.Value = CH_EXIT_CONFIRM.Checked
|
||||
.CloseToTray.Value = CH_CLOSE_TO_TRAY.Checked
|
||||
.ShowNotifications.Value = CH_SHOW_NOTIFY.Checked
|
||||
|
||||
If CH_FILE_NAME_CHANGE.Checked Then
|
||||
.FileReplaceNameByDate.Value = OPT_FILE_NAME_REPLACE.Checked
|
||||
@@ -180,24 +225,24 @@ Namespace Editors
|
||||
End If
|
||||
'Reddit
|
||||
With .Site(Sites.Reddit)
|
||||
SetPropByChecker(.Temporary, CH_REDDIT_TEMP)
|
||||
SetPropByChecker(.DownloadImages, CH_REDDIT_DOWN_IMG)
|
||||
SetPropByChecker(.DownloadVideos, CH_REDDIT_DOWN_VID)
|
||||
SetPropByChecker(DEFS_REDDIT, Sites.Reddit)
|
||||
.SavedPostsUserName.Value = TXT_REDDIT_SAVED_POSTS_USER.Text
|
||||
End With
|
||||
'Twitter
|
||||
With .Site(Sites.Twitter)
|
||||
SetPropByChecker(.Temporary, CH_TWITTER_TEMP)
|
||||
SetPropByChecker(.DownloadImages, CH_TWITTER_DOWN_IMG)
|
||||
SetPropByChecker(.DownloadVideos, CH_TWITTER_DOWN_VID)
|
||||
SetPropByChecker(DEFS_TWITTER, Sites.Twitter)
|
||||
.GetUserMediaOnly.Value = CH_TWITTER_USER_MEDIA.Checked
|
||||
End With
|
||||
'Instagram
|
||||
With .Site(Sites.Instagram)
|
||||
SetPropByChecker(.Temporary, CH_INSTA_TEMP)
|
||||
SetPropByChecker(.DownloadImages, CH_INSTA_DOWN_IMG)
|
||||
SetPropByChecker(.DownloadVideos, CH_INSTA_DOWN_VID)
|
||||
SetPropByChecker(DEFS_INST, Sites.Instagram)
|
||||
.RequestsWaitTimer.Value = AConvert(Of Integer)(TXT_REQ_WAIT_TIMER.Text)
|
||||
.RequestsWaitTimerTaskCount.Value = AConvert(Of Integer)(TXT_REQ_COUNT.Text)
|
||||
.SleepTimerOnPostsLimit.Value = AConvert(Of Integer)(TXT_LIMIT_TIMER.Text)
|
||||
.SavedPostsUserName.Value = TXT_INST_SAVED_POSTS_USER.Text
|
||||
End With
|
||||
'RedGifs
|
||||
SetPropByChecker(DEFS_REDGIFS, Sites.RedGifs)
|
||||
|
||||
.EndUpdate()
|
||||
End With
|
||||
|
||||
36
SCrawler/Editors/LabelsForm.Designer.vb
generated
36
SCrawler/Editors/LabelsForm.Designer.vb
generated
@@ -13,10 +13,10 @@ Partial Friend Class LabelsForm : Inherits System.Windows.Forms.Form
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(LabelsForm))
|
||||
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
Me.CMB_LABELS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||
Me.CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
@@ -42,21 +42,21 @@ Partial Friend Class LabelsForm : Inherits System.Windows.Forms.Form
|
||||
'
|
||||
'CMB_LABELS
|
||||
'
|
||||
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton4.Index = 0
|
||||
ActionButton4.Name = "BTT_COMBOBOX_ARROW"
|
||||
ActionButton4.Visible = False
|
||||
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton5.Index = 1
|
||||
ActionButton5.Name = "BTT_ADD"
|
||||
ActionButton5.ToolTipText = "Add new label (Insert)"
|
||||
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton6.Index = 2
|
||||
ActionButton6.Name = "BTT_CLEAR"
|
||||
ActionButton6.ToolTipText = "Clear checked labels"
|
||||
Me.CMB_LABELS.Buttons.Add(ActionButton4)
|
||||
Me.CMB_LABELS.Buttons.Add(ActionButton5)
|
||||
Me.CMB_LABELS.Buttons.Add(ActionButton6)
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Index = 0
|
||||
ActionButton1.Name = "BTT_COMBOBOX_ARROW"
|
||||
ActionButton1.Visible = False
|
||||
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton2.Index = 1
|
||||
ActionButton2.Name = "BTT_ADD"
|
||||
ActionButton2.ToolTipText = "Add new label (Insert)"
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Index = 2
|
||||
ActionButton3.Name = "BTT_CLEAR"
|
||||
ActionButton3.ToolTipText = "Clear checked labels"
|
||||
Me.CMB_LABELS.Buttons.Add(ActionButton1)
|
||||
Me.CMB_LABELS.Buttons.Add(ActionButton2)
|
||||
Me.CMB_LABELS.Buttons.Add(ActionButton3)
|
||||
Me.CMB_LABELS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CMB_LABELS.ListCheckBoxes = True
|
||||
Me.CMB_LABELS.ListDropDownStyle = PersonalUtilities.Forms.Controls.ComboBoxExtended.ListMode.Simple
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
|
||||
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
|
||||
@@ -208,7 +208,7 @@
|
||||
AAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlE
|
||||
@@ -230,7 +230,7 @@
|
||||
0AUyNxOP1DOwcaG/8I+/LRB+At7psBnyDBG0AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
|
||||
@@ -27,21 +27,18 @@ Friend Class LabelsForm : Implements IOkCancelToolbar
|
||||
Try
|
||||
With MyDefs
|
||||
.MyViewInitialize(Me, Settings.Design)
|
||||
.MyOkCancel = New OkCancelToolbar(Me, Me, CONTAINER_MAIN.BottomToolStripPanel)
|
||||
.MyOkCancel.AddThisToolbar()
|
||||
.AddOkCancelToolbar()
|
||||
.DelegateClosingChecker()
|
||||
|
||||
If Settings.Labels.Count > 0 Then
|
||||
Dim items As New List(Of Integer)
|
||||
CMB_LABELS.BeginUpdate()
|
||||
For i% = 0 To Settings.Labels.Count - 1
|
||||
If LabelsList.Contains(Settings.Labels(i)) Then items.Add(i)
|
||||
CMB_LABELS.Items.Add(New ListItem(Settings.Labels(i)))
|
||||
CMB_LABELS.Items.Add(Settings.Labels(i))
|
||||
Next
|
||||
CMB_LABELS.EndUpdate()
|
||||
CMB_LABELS.ListCheckedIndexes = items
|
||||
End If
|
||||
|
||||
.AppendDetectors()
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
@@ -60,8 +57,8 @@ Friend Class LabelsForm : Implements IOkCancelToolbar
|
||||
If MultiUser Then
|
||||
Dim m As New MMessage("You are changing labels for more one user" & vbNewLine & "What do you want to do?",
|
||||
"MultiUser labels changing",
|
||||
{New MsgBoxButton("Replace exists") With {.ToolTip = "For each user: all exists labels will be deleted and replaced to these labels"},
|
||||
New MsgBoxButton("Add to exists") With {.ToolTip = "For each user: these labels will be appended to exists labels"},
|
||||
{New MsgBoxButton("Replace exists") With {.ToolTip = "Per user: all existing labels will be removed and replaced with these labels"},
|
||||
New MsgBoxButton("Add to exists") With {.ToolTip = "Per user: these labels will be add to existing labels"},
|
||||
New MsgBoxButton("Cancel")},
|
||||
MsgBoxStyle.Exclamation)
|
||||
Select Case MsgBoxE(m).Index
|
||||
@@ -70,11 +67,7 @@ Friend Class LabelsForm : Implements IOkCancelToolbar
|
||||
Case 2 : Exit Sub
|
||||
End Select
|
||||
End If
|
||||
LabelsList.Clear()
|
||||
Dim s As List(Of Integer) = CMB_LABELS.ListCheckedIndexes.ListIfNothing
|
||||
If s.Count > 0 Then
|
||||
For Each i% In s : LabelsList.Add(Settings.Labels(i)) : Next
|
||||
End If
|
||||
LabelsList.ListAddList(CMB_LABELS.Items.CheckedItems.Select(Function(l) CStr(l.Value(0))), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||
If _AnyLabelAdd Then Settings.Labels.Update()
|
||||
MyDefs.CloseForm()
|
||||
Catch ex As Exception
|
||||
@@ -98,7 +91,7 @@ Friend Class LabelsForm : Implements IOkCancelToolbar
|
||||
Else
|
||||
Settings.Labels.Add(nl)
|
||||
_AnyLabelAdd = True
|
||||
CMB_LABELS.Items.Add(New ListItem(nl))
|
||||
CMB_LABELS.Items.Add(nl)
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
102
SCrawler/Editors/SiteDefaults.vb
Normal file
102
SCrawler/Editors/SiteDefaults.vb
Normal file
@@ -0,0 +1,102 @@
|
||||
' Copyright (C) 2022 Andy
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Namespace Editors
|
||||
Public Class SiteDefaults : Inherits TableLayoutPanel
|
||||
Private ReadOnly CH_TEMP As CheckBox
|
||||
Private ReadOnly CH_IMG As CheckBox
|
||||
Private ReadOnly CH_VID As CheckBox
|
||||
Public Sub New()
|
||||
InitCheckBox(CH_TEMP, "Temporary")
|
||||
InitCheckBox(CH_IMG, "Download images")
|
||||
InitCheckBox(CH_VID, "Download videos")
|
||||
End Sub
|
||||
Private Sub InitCheckBox(ByRef CH As CheckBox, ByVal Caption As String)
|
||||
CH = New CheckBox With {.Text = Caption, .Dock = DockStyle.Fill, .UseVisualStyleBackColor = True,
|
||||
.ThreeState = True, .CheckState = CheckState.Indeterminate}
|
||||
AddHandler CH.CheckedChanged, AddressOf Checker_CheckedChanged
|
||||
AddHandler CH.CheckStateChanged, AddressOf Checker_CheckedChanged
|
||||
End Sub
|
||||
Private Sub SiteDefaults_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
CH_TEMP.Dispose()
|
||||
CH_IMG.Dispose()
|
||||
CH_VID.Dispose()
|
||||
End Sub
|
||||
Protected Overrides Sub InitLayout()
|
||||
MyBase.InitLayout()
|
||||
If ColumnStyles.Count = 2 Or RowStyles.Count = 2 Then
|
||||
ColumnStyles.Clear()
|
||||
RowStyles.Clear()
|
||||
CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
|
||||
ColumnCount = 1
|
||||
ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
|
||||
RowCount = 4
|
||||
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
|
||||
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
|
||||
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
|
||||
RowStyles.Add(New RowStyle(SizeType.Percent, 100))
|
||||
End If
|
||||
Controls.Add(CH_TEMP, 0, 0)
|
||||
Controls.Add(CH_IMG, 0, 1)
|
||||
Controls.Add(CH_VID, 0, 2)
|
||||
End Sub
|
||||
Private _BaseControlsPadding As New Padding(0)
|
||||
<Browsable(True), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
|
||||
Category("Values"), DisplayName("Controls padding"), Description("Base controls padding")>
|
||||
Public Property BaseControlsPadding As Padding
|
||||
Get
|
||||
Return _BaseControlsPadding
|
||||
End Get
|
||||
Set(ByVal p As Padding)
|
||||
_BaseControlsPadding = p
|
||||
CH_TEMP.Padding = p
|
||||
CH_IMG.Padding = p
|
||||
CH_VID.Padding = p
|
||||
End Set
|
||||
End Property
|
||||
Private Function ShouldSerializeBaseControlsPadding() As Boolean
|
||||
Return Not _BaseControlsPadding.Equals(New Padding(0))
|
||||
End Function
|
||||
<Browsable(False), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
|
||||
Public Property ChangesDetected As Boolean = False
|
||||
Private Sub Checker_CheckedChanged(sender As Object, e As EventArgs)
|
||||
ChangesDetected = True
|
||||
End Sub
|
||||
<Browsable(True), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
|
||||
Category("Values"), DefaultValue(CheckState.Indeterminate), DisplayName("Temporary"), Description("Temporary profile")>
|
||||
Public Property MyTemporary As CheckState
|
||||
Get
|
||||
Return CH_TEMP.CheckState
|
||||
End Get
|
||||
Set(ByVal s As CheckState)
|
||||
CH_TEMP.CheckState = s
|
||||
End Set
|
||||
End Property
|
||||
<Browsable(True), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
|
||||
Category("Values"), DefaultValue(CheckState.Indeterminate), DisplayName("Images"), Description("Download images")>
|
||||
Public Property MyImagesDown As CheckState
|
||||
Get
|
||||
Return CH_IMG.CheckState
|
||||
End Get
|
||||
Set(ByVal s As CheckState)
|
||||
CH_IMG.CheckState = s
|
||||
End Set
|
||||
End Property
|
||||
<Browsable(True), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
|
||||
Category("Values"), DefaultValue(CheckState.Indeterminate), DisplayName("Videos"), Description("Download videos")>
|
||||
Public Property MyVideosDown As CheckState
|
||||
Get
|
||||
Return CH_VID.CheckState
|
||||
End Get
|
||||
Set(ByVal s As CheckState)
|
||||
CH_VID.CheckState = s
|
||||
End Set
|
||||
End Property
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -44,24 +44,28 @@ Namespace Editors
|
||||
TXT_AUTH.Text = .Headers(API.Base.SiteSettings.Header_Twitter_Authorization)
|
||||
End If
|
||||
End With
|
||||
If MySite = Sites.Instagram Then TXT_TOKEN.Text = .InstaHash
|
||||
If MySite = Sites.Instagram Then
|
||||
TXT_TOKEN.Text = .InstaHash
|
||||
TXT_AUTH.Text = .InstaHash_SP
|
||||
End If
|
||||
End With
|
||||
|
||||
If Not MySite = Sites.Twitter Then
|
||||
Dim p As PaddingE = PaddingE.GetOf({TP_MAIN})
|
||||
Dim s As New Size(Size.Width, Size.Height - p.Vertical - TXT_AUTH.NeededHeight)
|
||||
TXT_AUTH.Visible = False
|
||||
If Not MySite = Sites.Instagram Then
|
||||
s.Height -= (p.Vertical + TXT_TOKEN.NeededHeight)
|
||||
TXT_TOKEN.Visible = False
|
||||
Else
|
||||
If MySite = Sites.Twitter Or MySite = Sites.Instagram Then
|
||||
If MySite = Sites.Instagram Then
|
||||
TXT_TOKEN.CaptionText = "Hash"
|
||||
TXT_TOKEN.CaptionToolTipText = "Instagram session hash"
|
||||
TXT_TOKEN.Buttons.Clear()
|
||||
TXT_TOKEN.Buttons.AddRange({ActionButton.DefaultButtons.Refresh, ActionButton.DefaultButtons.Clear})
|
||||
TXT_AUTH.CaptionText = "Hash 2"
|
||||
TXT_AUTH.CaptionToolTipText = "Instagram session hash for saved posts"
|
||||
End If
|
||||
Else
|
||||
TXT_AUTH.Visible = False
|
||||
TXT_TOKEN.Visible = False
|
||||
Dim p As PaddingE = PaddingE.GetOf({TP_MAIN})
|
||||
Dim s As New Size(Size.Width, Size.Height - p.Vertical(2) - TXT_AUTH.NeededHeight - TXT_TOKEN.NeededHeight)
|
||||
With TP_MAIN
|
||||
If Not MySite = Sites.Instagram Then .RowStyles(2).Height = 0
|
||||
.RowStyles(2).Height = 0
|
||||
.RowStyles(3).Height = 0
|
||||
End With
|
||||
MinimumSize = s
|
||||
@@ -71,9 +75,9 @@ Namespace Editors
|
||||
|
||||
.MyFieldsChecker = New FieldsChecker
|
||||
With .MyFieldsChecker
|
||||
If MySite = Sites.Twitter Then
|
||||
If MySite = Sites.Twitter Or MySite = Sites.Instagram Then
|
||||
.AddControl(Of String)(TXT_TOKEN, TXT_TOKEN.CaptionText)
|
||||
.AddControl(Of String)(TXT_AUTH, TXT_AUTH.CaptionText)
|
||||
.AddControl(Of String)(TXT_AUTH, TXT_AUTH.CaptionText, MySite = Sites.Instagram)
|
||||
End If
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
@@ -86,6 +90,12 @@ Namespace Editors
|
||||
End Sub
|
||||
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
|
||||
If MyDefs.MyFieldsChecker.AllParamsOK Then
|
||||
If MySite = Sites.Instagram Then
|
||||
If Not TXT_TOKEN.IsEmptyString AndAlso Not TXT_AUTH.IsEmptyString AndAlso TXT_TOKEN.Text = TXT_AUTH.Text Then
|
||||
MsgBoxE({"InstaHash for saved posts must be different from InstaHash!", "InstaHash are equal"}, vbCritical)
|
||||
Exit Sub
|
||||
End If
|
||||
End If
|
||||
With Settings(MySite)
|
||||
If TXT_PATH.IsEmptyString Then .Path = Nothing Else .Path = TXT_PATH.Text
|
||||
Select Case MySite
|
||||
@@ -96,6 +106,7 @@ Namespace Editors
|
||||
End With
|
||||
Case Sites.Instagram
|
||||
.InstaHash.Value = TXT_TOKEN.Text
|
||||
.InstaHash_SP.Value = TXT_AUTH.Text
|
||||
End Select
|
||||
.Update()
|
||||
End With
|
||||
|
||||
@@ -25,15 +25,11 @@ Namespace Editors
|
||||
.DelegateClosingChecker()
|
||||
.AddOkCancelToolbar()
|
||||
CMB_SITES.BeginUpdate()
|
||||
CMB_SITES.Items.AddRange({New ListItem({Sites.Reddit.ToString, CInt(Sites.Reddit)}),
|
||||
New ListItem({Sites.Twitter.ToString, CInt(Sites.Twitter)}),
|
||||
New ListItem({Sites.Instagram.ToString, CInt(Sites.Instagram)})})
|
||||
Dim sl As List(Of Sites) = ListAddList(Of Sites)(Nothing, [Enum].GetValues(GetType(Sites))).ListWithRemove(Sites.Undefined)
|
||||
CMB_SITES.Items.AddRange(sl.Select(Function(s) New ListItem({s.ToString, CInt(s)})))
|
||||
Dim l As New List(Of Integer)
|
||||
If SelectedSites.Count > 0 Then
|
||||
If SelectedSites.Contains(Sites.Reddit) Then l.Add(0)
|
||||
If SelectedSites.Contains(Sites.Twitter) Then l.Add(1)
|
||||
If SelectedSites.Contains(Sites.Instagram) Then l.Add(2)
|
||||
End If
|
||||
If SelectedSites.Count > 0 Then sl.ForEach(Sub(s) If SelectedSites.Contains(s) Then l.Add(sl.IndexOf(s)))
|
||||
sl.Clear()
|
||||
CMB_SITES.EndUpdate()
|
||||
If l.Count > 0 Then CMB_SITES.ListCheckedIndexes = l : l.Clear()
|
||||
.EndLoaderOperations()
|
||||
@@ -45,17 +41,7 @@ Namespace Editors
|
||||
End Sub
|
||||
Public Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
|
||||
Try
|
||||
SelectedSites.Clear()
|
||||
Dim l As List(Of Integer) = CMB_SITES.ListCheckedIndexes
|
||||
If l.ListExists Then
|
||||
For Each i% In l
|
||||
Select Case i
|
||||
Case 0 : SelectedSites.Add(Sites.Reddit)
|
||||
Case 1 : SelectedSites.Add(Sites.Twitter)
|
||||
Case 2 : SelectedSites.Add(Sites.Instagram)
|
||||
End Select
|
||||
Next
|
||||
End If
|
||||
SelectedSites.ListAddList(CMB_SITES.Items.CheckedItems.Select(Function(i) DirectCast(i.Value(1), Sites)), LAP.ClearBeforeAdd)
|
||||
MyDefs.CloseForm()
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.LogMessageValue, ex)
|
||||
|
||||
78
SCrawler/Editors/UserCreatorForm.Designer.vb
generated
78
SCrawler/Editors/UserCreatorForm.Designer.vb
generated
@@ -16,7 +16,6 @@
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_SITE As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_PARAMS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_OTHER As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
@@ -28,10 +27,12 @@
|
||||
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.TXT_USER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TP_SITE = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.OPT_REDDIT = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_TWITTER = New System.Windows.Forms.RadioButton()
|
||||
Me.CH_IS_CHANNEL = New System.Windows.Forms.CheckBox()
|
||||
Me.OPT_INSTAGRAM = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_REDGIFS = New System.Windows.Forms.RadioButton()
|
||||
Me.CH_TEMP = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_FAV = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_PARSE_USER_MEDIA = New System.Windows.Forms.CheckBox()
|
||||
@@ -47,14 +48,13 @@
|
||||
Me.TXT_SPEC_FOLDER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_SITE = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_PARAMS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_OTHER = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_DOWN_OPTIONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
TP_MAIN.SuspendLayout()
|
||||
CType(Me.TXT_USER, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TP_SITE.SuspendLayout()
|
||||
Me.TP_SITE.SuspendLayout()
|
||||
TP_PARAMS.SuspendLayout()
|
||||
TP_OTHER.SuspendLayout()
|
||||
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
@@ -73,7 +73,7 @@
|
||||
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_USER, 0, 0)
|
||||
TP_MAIN.Controls.Add(TP_SITE, 0, 3)
|
||||
TP_MAIN.Controls.Add(Me.TP_SITE, 0, 3)
|
||||
TP_MAIN.Controls.Add(TP_PARAMS, 0, 4)
|
||||
TP_MAIN.Controls.Add(TP_OTHER, 0, 6)
|
||||
TP_MAIN.Controls.Add(Me.TXT_DESCR, 0, 9)
|
||||
@@ -112,24 +112,26 @@
|
||||
'
|
||||
'TP_SITE
|
||||
'
|
||||
TP_SITE.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
TP_SITE.ColumnCount = 4
|
||||
TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_SITE.Controls.Add(Me.OPT_REDDIT, 0, 0)
|
||||
TP_SITE.Controls.Add(Me.OPT_TWITTER, 2, 0)
|
||||
TP_SITE.Controls.Add(Me.CH_IS_CHANNEL, 1, 0)
|
||||
TP_SITE.Controls.Add(Me.OPT_INSTAGRAM, 3, 0)
|
||||
TP_SITE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_SITE.Location = New System.Drawing.Point(1, 88)
|
||||
TP_SITE.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_SITE.Name = "TP_SITE"
|
||||
TP_SITE.RowCount = 1
|
||||
TP_SITE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_SITE.Size = New System.Drawing.Size(452, 31)
|
||||
TP_SITE.TabIndex = 3
|
||||
Me.TP_SITE.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
Me.TP_SITE.ColumnCount = 5
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0!))
|
||||
Me.TP_SITE.Controls.Add(Me.OPT_REDDIT, 0, 0)
|
||||
Me.TP_SITE.Controls.Add(Me.OPT_TWITTER, 2, 0)
|
||||
Me.TP_SITE.Controls.Add(Me.CH_IS_CHANNEL, 1, 0)
|
||||
Me.TP_SITE.Controls.Add(Me.OPT_INSTAGRAM, 3, 0)
|
||||
Me.TP_SITE.Controls.Add(Me.OPT_REDGIFS, 4, 0)
|
||||
Me.TP_SITE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_SITE.Location = New System.Drawing.Point(1, 88)
|
||||
Me.TP_SITE.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.TP_SITE.Name = "TP_SITE"
|
||||
Me.TP_SITE.RowCount = 1
|
||||
Me.TP_SITE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_SITE.Size = New System.Drawing.Size(452, 31)
|
||||
Me.TP_SITE.TabIndex = 3
|
||||
'
|
||||
'OPT_REDDIT
|
||||
'
|
||||
@@ -137,7 +139,7 @@
|
||||
Me.OPT_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_REDDIT.Location = New System.Drawing.Point(4, 4)
|
||||
Me.OPT_REDDIT.Name = "OPT_REDDIT"
|
||||
Me.OPT_REDDIT.Size = New System.Drawing.Size(105, 23)
|
||||
Me.OPT_REDDIT.Size = New System.Drawing.Size(83, 23)
|
||||
Me.OPT_REDDIT.TabIndex = 0
|
||||
Me.OPT_REDDIT.TabStop = True
|
||||
Me.OPT_REDDIT.Text = "Reddit"
|
||||
@@ -147,9 +149,9 @@
|
||||
'
|
||||
Me.OPT_TWITTER.AutoSize = True
|
||||
Me.OPT_TWITTER.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_TWITTER.Location = New System.Drawing.Point(228, 4)
|
||||
Me.OPT_TWITTER.Location = New System.Drawing.Point(184, 4)
|
||||
Me.OPT_TWITTER.Name = "OPT_TWITTER"
|
||||
Me.OPT_TWITTER.Size = New System.Drawing.Size(105, 23)
|
||||
Me.OPT_TWITTER.Size = New System.Drawing.Size(83, 23)
|
||||
Me.OPT_TWITTER.TabIndex = 1
|
||||
Me.OPT_TWITTER.TabStop = True
|
||||
Me.OPT_TWITTER.Text = "Twitter"
|
||||
@@ -159,9 +161,9 @@
|
||||
'
|
||||
Me.CH_IS_CHANNEL.AutoSize = True
|
||||
Me.CH_IS_CHANNEL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_IS_CHANNEL.Location = New System.Drawing.Point(116, 4)
|
||||
Me.CH_IS_CHANNEL.Location = New System.Drawing.Point(94, 4)
|
||||
Me.CH_IS_CHANNEL.Name = "CH_IS_CHANNEL"
|
||||
Me.CH_IS_CHANNEL.Size = New System.Drawing.Size(105, 23)
|
||||
Me.CH_IS_CHANNEL.Size = New System.Drawing.Size(83, 23)
|
||||
Me.CH_IS_CHANNEL.TabIndex = 2
|
||||
Me.CH_IS_CHANNEL.Text = "Channel"
|
||||
Me.CH_IS_CHANNEL.UseVisualStyleBackColor = True
|
||||
@@ -170,14 +172,26 @@
|
||||
'
|
||||
Me.OPT_INSTAGRAM.AutoSize = True
|
||||
Me.OPT_INSTAGRAM.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_INSTAGRAM.Location = New System.Drawing.Point(340, 4)
|
||||
Me.OPT_INSTAGRAM.Location = New System.Drawing.Point(274, 4)
|
||||
Me.OPT_INSTAGRAM.Name = "OPT_INSTAGRAM"
|
||||
Me.OPT_INSTAGRAM.Size = New System.Drawing.Size(108, 23)
|
||||
Me.OPT_INSTAGRAM.Size = New System.Drawing.Size(83, 23)
|
||||
Me.OPT_INSTAGRAM.TabIndex = 3
|
||||
Me.OPT_INSTAGRAM.TabStop = True
|
||||
Me.OPT_INSTAGRAM.Text = "Instagram"
|
||||
Me.OPT_INSTAGRAM.UseVisualStyleBackColor = True
|
||||
'
|
||||
'OPT_REDGIFS
|
||||
'
|
||||
Me.OPT_REDGIFS.AutoSize = True
|
||||
Me.OPT_REDGIFS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_REDGIFS.Location = New System.Drawing.Point(364, 4)
|
||||
Me.OPT_REDGIFS.Name = "OPT_REDGIFS"
|
||||
Me.OPT_REDGIFS.Size = New System.Drawing.Size(84, 23)
|
||||
Me.OPT_REDGIFS.TabIndex = 4
|
||||
Me.OPT_REDGIFS.TabStop = True
|
||||
Me.OPT_REDGIFS.Text = "RedGifs"
|
||||
Me.OPT_REDGIFS.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_PARAMS
|
||||
'
|
||||
TP_PARAMS.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
@@ -442,8 +456,8 @@
|
||||
Me.Text = "Create User"
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
CType(Me.TXT_USER, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TP_SITE.ResumeLayout(False)
|
||||
TP_SITE.PerformLayout()
|
||||
Me.TP_SITE.ResumeLayout(False)
|
||||
Me.TP_SITE.PerformLayout()
|
||||
TP_PARAMS.ResumeLayout(False)
|
||||
TP_PARAMS.PerformLayout()
|
||||
TP_OTHER.ResumeLayout(False)
|
||||
@@ -482,5 +496,7 @@
|
||||
Private WithEvents CH_IS_CHANNEL As CheckBox
|
||||
Private WithEvents OPT_INSTAGRAM As RadioButton
|
||||
Private WithEvents TXT_SPEC_FOLDER As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents OPT_REDGIFS As RadioButton
|
||||
Private WithEvents TP_SITE As TableLayoutPanel
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -120,9 +120,6 @@
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_SITE.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_PARAMS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Controls
|
||||
Imports PersonalUtilities.Forms.Controls.Base
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API.Base
|
||||
@@ -119,13 +118,11 @@ Namespace Editors
|
||||
Case Sites.Reddit : OPT_REDDIT.Checked = True : CH_PARSE_USER_MEDIA.Enabled = False
|
||||
Case Sites.Twitter : OPT_TWITTER.Checked = True
|
||||
Case Sites.Instagram : OPT_INSTAGRAM.Checked = True
|
||||
Case Sites.RedGifs : OPT_REDGIFS.Checked = True
|
||||
End Select
|
||||
SetParamsBySite()
|
||||
OPT_REDDIT.Enabled = False
|
||||
OPT_TWITTER.Enabled = False
|
||||
OPT_INSTAGRAM.Enabled = False
|
||||
TP_SITE.Enabled = False
|
||||
CH_IS_CHANNEL.Checked = User.IsChannel
|
||||
CH_IS_CHANNEL.Enabled = False
|
||||
If Not UserInstance Is Nothing Then
|
||||
TXT_USER.Enabled = False
|
||||
TXT_SPEC_FOLDER.TextBoxReadOnly = True
|
||||
@@ -179,6 +176,7 @@ Namespace Editors
|
||||
Case OPT_REDDIT.Checked : Return Sites.Reddit
|
||||
Case OPT_TWITTER.Checked : Return Sites.Twitter
|
||||
Case OPT_INSTAGRAM.Checked : Return Sites.Instagram
|
||||
Case OPT_REDGIFS.Checked : Return Sites.RedGifs
|
||||
Case Else : Return Sites.Undefined
|
||||
End Select
|
||||
End Function
|
||||
@@ -239,6 +237,7 @@ CloseForm:
|
||||
Private ReadOnly RedditChannelRegEx1 As New RegexStructure("[htps:/]{7,8}.*?reddit.com/r/([^/]+)", 1)
|
||||
Private ReadOnly RedditChannelRegEx2 As New RegexStructure(".?r/([^/]+)", 1)
|
||||
Private ReadOnly InstagramRegEx As New RegexStructure("[htps:/]{7,8}.*?instagram.com/([^/]+)", 1)
|
||||
Private ReadOnly RedGifsRegEx As New RegexStructure("[htps:/]{7,8}.*?redgifs.com/users/([^/]+)", 1)
|
||||
Private _TextChangeInvoked As Boolean = False
|
||||
Private Sub TXT_USER_ActionOnTextChange() Handles TXT_USER.ActionOnTextChange
|
||||
Try
|
||||
@@ -250,6 +249,7 @@ CloseForm:
|
||||
Case Sites.Twitter : OPT_TWITTER.Checked = True
|
||||
Case Sites.Reddit : OPT_REDDIT.Checked = True
|
||||
Case Sites.Instagram : OPT_INSTAGRAM.Checked = True
|
||||
Case Sites.RedGifs : OPT_REDGIFS.Checked = True
|
||||
Case Else : OPT_TWITTER.Checked = False : OPT_REDDIT.Checked = False : OPT_INSTAGRAM.Checked = False
|
||||
End Select
|
||||
CH_IS_CHANNEL.Checked = CBool(s(1))
|
||||
@@ -269,6 +269,8 @@ CloseForm:
|
||||
Return {Sites.Reddit, True}
|
||||
ElseIf CheckRegex(TXT, InstagramRegEx) Then
|
||||
Return {Sites.Instagram, False}
|
||||
ElseIf CheckRegex(TXT, RedGifsRegEx) Then
|
||||
Return {Sites.RedGifs, False}
|
||||
End If
|
||||
End If
|
||||
Return {Sites.Undefined, False}
|
||||
@@ -286,6 +288,9 @@ CloseForm:
|
||||
Private Sub OPT_INSTAGRAM_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_INSTAGRAM.CheckedChanged
|
||||
If OPT_INSTAGRAM.Checked Then CH_IS_CHANNEL.Checked = False : CH_IS_CHANNEL.Enabled = False : SetParamsBySite()
|
||||
End Sub
|
||||
Private Sub OPT_REDGIFS_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_REDGIFS.CheckedChanged
|
||||
If OPT_REDGIFS.Checked Then CH_IS_CHANNEL.Checked = False : CH_IS_CHANNEL.Enabled = False : SetParamsBySite()
|
||||
End Sub
|
||||
Private Sub TXT_SPEC_FOLDER_ActionOnButtonClick(ByVal Sender As ActionButton) Handles TXT_SPEC_FOLDER.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ActionButton.DefaultButtons.Open Then
|
||||
Dim f As SFile = Nothing
|
||||
|
||||
114
SCrawler/MainFrame.Designer.vb
generated
114
SCrawler/MainFrame.Designer.vb
generated
@@ -1,8 +1,5 @@
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Class MainFrame
|
||||
Inherits System.Windows.Forms.Form
|
||||
|
||||
'Form overrides dispose to clean up the component list.
|
||||
Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
@@ -13,13 +10,7 @@ Partial Class MainFrame
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
'Required by the Windows Form Designer
|
||||
Private components As System.ComponentModel.IContainer
|
||||
|
||||
'NOTE: The following procedure is required by the Windows Form Designer
|
||||
'It can be modified using the Windows Form Designer.
|
||||
'Do not modify it using the code editor.
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
@@ -37,10 +28,12 @@ Partial Class MainFrame
|
||||
Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim MENU_VIEW_SEP_3 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim MENU_VIEW_SEP_2 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim TRAY_SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MainFrame))
|
||||
Me.BTT_SETTINGS_REDDIT = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_SETTINGS_TWITTER = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_SETTINGS_INSTAGRAM = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_SETTINGS_REDGIFS = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_SETTINGS = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.Toolbar_TOP = New System.Windows.Forms.ToolStrip()
|
||||
Me.BTT_ADD_USER = New System.Windows.Forms.ToolStripButton()
|
||||
@@ -69,11 +62,14 @@ Partial Class MainFrame
|
||||
Me.BTT_SELECT_LABELS = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_LOG = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_VERSION_INFO = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_DONATE = New System.Windows.Forms.ToolStripButton()
|
||||
Me.Toolbar_BOTTOM = New System.Windows.Forms.StatusStrip()
|
||||
Me.PR_SAVED = New System.Windows.Forms.ToolStripProgressBar()
|
||||
Me.PR_MAIN = New System.Windows.Forms.ToolStripProgressBar()
|
||||
Me.LBL_JOBS_COUNT = New System.Windows.Forms.ToolStripStatusLabel()
|
||||
Me.LBL_STATUS = New System.Windows.Forms.ToolStripStatusLabel()
|
||||
Me.PR_INST = New System.Windows.Forms.ToolStripProgressBar()
|
||||
Me.LBL_JOBS_INST_COUNT = New System.Windows.Forms.ToolStripStatusLabel()
|
||||
Me.LBL_STATUS_INST = New System.Windows.Forms.ToolStripStatusLabel()
|
||||
Me.LIST_PROFILES = New System.Windows.Forms.ListView()
|
||||
Me.USER_CONTEXT = New System.Windows.Forms.ContextMenuStrip(Me.components)
|
||||
Me.BTT_CONTEXT_DOWN = New System.Windows.Forms.ToolStripMenuItem()
|
||||
@@ -91,6 +87,10 @@ Partial Class MainFrame
|
||||
Me.BTT_CONTEXT_OPEN_PATH = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_CONTEXT_OPEN_SITE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_CONTEXT_INFO = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.TrayIcon = New System.Windows.Forms.NotifyIcon(Me.components)
|
||||
Me.TRAY_CONTEXT = New System.Windows.Forms.ContextMenuStrip(Me.components)
|
||||
Me.BTT_TRAY_SHOW_HIDE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_CLOSE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
@@ -105,9 +105,11 @@ Partial Class MainFrame
|
||||
MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
MENU_VIEW_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
|
||||
MENU_VIEW_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||
TRAY_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
Me.Toolbar_TOP.SuspendLayout()
|
||||
Me.Toolbar_BOTTOM.SuspendLayout()
|
||||
Me.USER_CONTEXT.SuspendLayout()
|
||||
Me.TRAY_CONTEXT.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'SEP_1
|
||||
@@ -128,7 +130,7 @@ Partial Class MainFrame
|
||||
'MENU_SETTINGS
|
||||
'
|
||||
MENU_SETTINGS.AutoToolTip = False
|
||||
MENU_SETTINGS.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_SETTINGS_REDDIT, Me.BTT_SETTINGS_TWITTER, Me.BTT_SETTINGS_INSTAGRAM, MENU_SETTINGS_SEP_1, Me.BTT_SETTINGS})
|
||||
MENU_SETTINGS.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_SETTINGS_REDDIT, Me.BTT_SETTINGS_TWITTER, Me.BTT_SETTINGS_INSTAGRAM, Me.BTT_SETTINGS_REDGIFS, MENU_SETTINGS_SEP_1, Me.BTT_SETTINGS})
|
||||
MENU_SETTINGS.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||
MENU_SETTINGS.Name = "MENU_SETTINGS"
|
||||
MENU_SETTINGS.Size = New System.Drawing.Size(62, 22)
|
||||
@@ -155,6 +157,12 @@ Partial Class MainFrame
|
||||
Me.BTT_SETTINGS_INSTAGRAM.Size = New System.Drawing.Size(127, 22)
|
||||
Me.BTT_SETTINGS_INSTAGRAM.Text = "Instagram"
|
||||
'
|
||||
'BTT_SETTINGS_REDGIFS
|
||||
'
|
||||
Me.BTT_SETTINGS_REDGIFS.Name = "BTT_SETTINGS_REDGIFS"
|
||||
Me.BTT_SETTINGS_REDGIFS.Size = New System.Drawing.Size(127, 22)
|
||||
Me.BTT_SETTINGS_REDGIFS.Text = "RedGifs"
|
||||
'
|
||||
'MENU_SETTINGS_SEP_1
|
||||
'
|
||||
MENU_SETTINGS_SEP_1.Name = "MENU_SETTINGS_SEP_1"
|
||||
@@ -212,10 +220,15 @@ Partial Class MainFrame
|
||||
MENU_VIEW_SEP_2.Name = "MENU_VIEW_SEP_2"
|
||||
MENU_VIEW_SEP_2.Size = New System.Drawing.Size(141, 6)
|
||||
'
|
||||
'TRAY_SEP_1
|
||||
'
|
||||
TRAY_SEP_1.Name = "TRAY_SEP_1"
|
||||
TRAY_SEP_1.Size = New System.Drawing.Size(130, 6)
|
||||
'
|
||||
'Toolbar_TOP
|
||||
'
|
||||
Me.Toolbar_TOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||
Me.Toolbar_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {MENU_SETTINGS, SEP_1, Me.BTT_ADD_USER, Me.BTT_EDIT_USER, Me.BTT_DELETE_USER, Me.BTT_REFRESH, Me.BTT_SHOW_INFO, Me.BTT_CHANNELS, Me.BTT_DOWN_SAVED, SEP_2, Me.BTT_DOWN_SELECTED, Me.BTT_DOWN_ALL, Me.BTT_DOWN_VIDEO, Me.BTT_DOWN_STOP, SEP_3, Me.MENU_VIEW, SEP_4, Me.BTT_LOG, Me.BTT_VERSION_INFO})
|
||||
Me.Toolbar_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {MENU_SETTINGS, SEP_1, Me.BTT_ADD_USER, Me.BTT_EDIT_USER, Me.BTT_DELETE_USER, Me.BTT_REFRESH, Me.BTT_SHOW_INFO, Me.BTT_CHANNELS, Me.BTT_DOWN_SAVED, SEP_2, Me.BTT_DOWN_SELECTED, Me.BTT_DOWN_ALL, Me.BTT_DOWN_VIDEO, Me.BTT_DOWN_STOP, SEP_3, Me.MENU_VIEW, SEP_4, Me.BTT_LOG, Me.BTT_VERSION_INFO, Me.BTT_DONATE})
|
||||
Me.Toolbar_TOP.Location = New System.Drawing.Point(0, 0)
|
||||
Me.Toolbar_TOP.Name = "Toolbar_TOP"
|
||||
Me.Toolbar_TOP.Size = New System.Drawing.Size(934, 25)
|
||||
@@ -426,20 +439,25 @@ Partial Class MainFrame
|
||||
Me.BTT_VERSION_INFO.Text = "Info"
|
||||
Me.BTT_VERSION_INFO.ToolTipText = "Show program information and check for new version"
|
||||
'
|
||||
'BTT_DONATE
|
||||
'
|
||||
Me.BTT_DONATE.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
|
||||
Me.BTT_DONATE.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
|
||||
Me.BTT_DONATE.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
|
||||
Me.BTT_DONATE.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||
Me.BTT_DONATE.Name = "BTT_DONATE"
|
||||
Me.BTT_DONATE.Size = New System.Drawing.Size(23, 20)
|
||||
Me.BTT_DONATE.Text = "Donate"
|
||||
Me.BTT_DONATE.ToolTipText = "Donate"
|
||||
'
|
||||
'Toolbar_BOTTOM
|
||||
'
|
||||
Me.Toolbar_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_SAVED, Me.PR_MAIN, Me.LBL_JOBS_COUNT, Me.LBL_STATUS})
|
||||
Me.Toolbar_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_MAIN, Me.LBL_JOBS_COUNT, Me.LBL_STATUS, Me.PR_INST, Me.LBL_JOBS_INST_COUNT, Me.LBL_STATUS_INST})
|
||||
Me.Toolbar_BOTTOM.Location = New System.Drawing.Point(0, 439)
|
||||
Me.Toolbar_BOTTOM.Name = "Toolbar_BOTTOM"
|
||||
Me.Toolbar_BOTTOM.Size = New System.Drawing.Size(934, 22)
|
||||
Me.Toolbar_BOTTOM.TabIndex = 2
|
||||
'
|
||||
'PR_SAVED
|
||||
'
|
||||
Me.PR_SAVED.Name = "PR_SAVED"
|
||||
Me.PR_SAVED.Size = New System.Drawing.Size(100, 16)
|
||||
Me.PR_SAVED.Visible = False
|
||||
'
|
||||
'PR_MAIN
|
||||
'
|
||||
Me.PR_MAIN.Name = "PR_MAIN"
|
||||
@@ -456,6 +474,22 @@ Partial Class MainFrame
|
||||
Me.LBL_STATUS.Name = "LBL_STATUS"
|
||||
Me.LBL_STATUS.Size = New System.Drawing.Size(0, 17)
|
||||
'
|
||||
'PR_INST
|
||||
'
|
||||
Me.PR_INST.Name = "PR_INST"
|
||||
Me.PR_INST.Size = New System.Drawing.Size(200, 16)
|
||||
Me.PR_INST.Visible = False
|
||||
'
|
||||
'LBL_JOBS_INST_COUNT
|
||||
'
|
||||
Me.LBL_JOBS_INST_COUNT.Name = "LBL_JOBS_INST_COUNT"
|
||||
Me.LBL_JOBS_INST_COUNT.Size = New System.Drawing.Size(0, 17)
|
||||
'
|
||||
'LBL_STATUS_INST
|
||||
'
|
||||
Me.LBL_STATUS_INST.Name = "LBL_STATUS_INST"
|
||||
Me.LBL_STATUS_INST.Size = New System.Drawing.Size(0, 17)
|
||||
'
|
||||
'LIST_PROFILES
|
||||
'
|
||||
Me.LIST_PROFILES.Activation = System.Windows.Forms.ItemActivation.OneClick
|
||||
@@ -580,6 +614,35 @@ Partial Class MainFrame
|
||||
Me.BTT_CONTEXT_INFO.Size = New System.Drawing.Size(221, 22)
|
||||
Me.BTT_CONTEXT_INFO.Text = "Information"
|
||||
'
|
||||
'TrayIcon
|
||||
'
|
||||
Me.TrayIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info
|
||||
Me.TrayIcon.BalloonTipTitle = "Social networks crawler"
|
||||
Me.TrayIcon.ContextMenuStrip = Me.TRAY_CONTEXT
|
||||
Me.TrayIcon.Icon = CType(resources.GetObject("TrayIcon.Icon"), System.Drawing.Icon)
|
||||
Me.TrayIcon.Text = "Social networks crawler"
|
||||
'
|
||||
'TRAY_CONTEXT
|
||||
'
|
||||
Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_1, Me.BTT_TRAY_CLOSE})
|
||||
Me.TRAY_CONTEXT.Name = "TRAY_CONTEXT"
|
||||
Me.TRAY_CONTEXT.Size = New System.Drawing.Size(134, 54)
|
||||
'
|
||||
'BTT_TRAY_SHOW_HIDE
|
||||
'
|
||||
Me.BTT_TRAY_SHOW_HIDE.Name = "BTT_TRAY_SHOW_HIDE"
|
||||
Me.BTT_TRAY_SHOW_HIDE.Size = New System.Drawing.Size(133, 22)
|
||||
Me.BTT_TRAY_SHOW_HIDE.Text = "Show/Hide"
|
||||
'
|
||||
'BTT_TRAY_CLOSE
|
||||
'
|
||||
Me.BTT_TRAY_CLOSE.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(192, Byte), Integer))
|
||||
Me.BTT_TRAY_CLOSE.ForeColor = System.Drawing.Color.Maroon
|
||||
Me.BTT_TRAY_CLOSE.Image = CType(resources.GetObject("BTT_TRAY_CLOSE.Image"), System.Drawing.Image)
|
||||
Me.BTT_TRAY_CLOSE.Name = "BTT_TRAY_CLOSE"
|
||||
Me.BTT_TRAY_CLOSE.Size = New System.Drawing.Size(133, 22)
|
||||
Me.BTT_TRAY_CLOSE.Text = "Close"
|
||||
'
|
||||
'MainFrame
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
@@ -598,6 +661,7 @@ Partial Class MainFrame
|
||||
Me.Toolbar_BOTTOM.ResumeLayout(False)
|
||||
Me.Toolbar_BOTTOM.PerformLayout()
|
||||
Me.USER_CONTEXT.ResumeLayout(False)
|
||||
Me.TRAY_CONTEXT.ResumeLayout(False)
|
||||
Me.ResumeLayout(False)
|
||||
Me.PerformLayout()
|
||||
|
||||
@@ -654,6 +718,14 @@ Partial Class MainFrame
|
||||
Private WithEvents BTT_SITE_ALL As ToolStripMenuItem
|
||||
Private WithEvents BTT_SITE_SPECIFIC As ToolStripMenuItem
|
||||
Private WithEvents BTT_CONTEXT_CHANGE_FOLDER As ToolStripMenuItem
|
||||
Private WithEvents PR_SAVED As ToolStripProgressBar
|
||||
Private WithEvents BTT_DOWN_SAVED As ToolStripButton
|
||||
Private WithEvents PR_INST As ToolStripProgressBar
|
||||
Private WithEvents LBL_JOBS_INST_COUNT As ToolStripStatusLabel
|
||||
Private WithEvents LBL_STATUS_INST As ToolStripStatusLabel
|
||||
Private WithEvents TrayIcon As NotifyIcon
|
||||
Private WithEvents TRAY_CONTEXT As ContextMenuStrip
|
||||
Private WithEvents BTT_TRAY_SHOW_HIDE As ToolStripMenuItem
|
||||
Private WithEvents BTT_TRAY_CLOSE As ToolStripMenuItem
|
||||
Private WithEvents BTT_SETTINGS_REDGIFS As ToolStripMenuItem
|
||||
Private WithEvents BTT_DONATE As ToolStripButton
|
||||
End Class
|
||||
@@ -159,6 +159,9 @@
|
||||
<metadata name="MENU_VIEW_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TRAY_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="Toolbar_TOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>132, 17</value>
|
||||
</metadata>
|
||||
@@ -295,6 +298,207 @@
|
||||
At+48gfYvPlXp/n+iqDm2Lj4f73w4kt1S+yWJa3+1e9fQ5Bp8ZkfwPMCwN9yOBn2+KfAk+ChX8G+Dps/
|
||||
r1u/xd3D6+rf/v5+9YqVq6Sv/vF9Xh2XnFf8yCt5XGzeWrdeY+/glPLrtRte+M1bG1dBlPfP4uvT/xKb
|
||||
N95xYLfifeVScsnnXMZvA+8pi/7fhb+CbP4D9GPXvMEwYYwAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TrayIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>525, 17</value>
|
||||
</metadata>
|
||||
<metadata name="TRAY_CONTEXT.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>623, 17</value>
|
||||
</metadata>
|
||||
<data name="BTT_TRAY_CLOSE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
|
||||
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAVoSURBVEhLhZVrTJNXGMdfrtNSQIoadKRz2o0CorU3
|
||||
WkDIVBRaaGNbwAteh+AARRQlitEYTTRekiX7sH3YPmyZH9wtziybigLRCWTaCW5sCBWhlrb0Ci9zSxbo
|
||||
2f+UliGX7SS/tO85z/k9T57zXhhCCPO7Wh3VIhB83JKQ0Nu4bNlHm5YseZ1hmHC69n+Y5HLFcz7/ft/S
|
||||
pY+vr1hhwL4oEBJcZ0x793If5uZ+1VNfT/qvXCHP6+p8tzMymqRxcW8hMGKqbDo9MlmWddu2AfbiRTJ6
|
||||
+TIZKC52fyAUVi2JiYkLJmGaBYIPnx4+TPrOnCH9p08TC4LNx46RWwrF/ZXR0W/PleRZZuY669atZvbS
|
||||
JcJiL9vQQEZPnSKmwkLPjcTE97GPB8KZlvh4C5X31dWRgRMniAVBtvPnyWB9ve+2XP7jmtjYpOlJTOnp
|
||||
G60lJRZaOZWPQs4ePUpGUZh3xw7SnJDQhT0KEM3c5fOv9paVkX4kMAPL8ePEig1D584RG9rVpFS2rY6J
|
||||
EQaTmKTSjbbiYsvIhQuERTGjKIrFvtHaWjK8fz9plsudexYu/BLxKsBj9ALBGzel0vt9e/b4XiBoENhQ
|
||||
zRDOxIWWOY4cIS0KRZs4Nja5QyLJtRoM1pGzZ/0tYVExi/ayNTVkBPJ76enuJA7nM4j3gVWAHjgTIYqL
|
||||
E96SStvMu3YR64EDxF5dTYYOHSJOJPNA5Kiu9rUrlZ1mrdbCnjzpr5jFGotYtqpqQi6TuVM4nKvwlYHU
|
||||
gDzU31OMSGl8fPJtsbjVsn27z15RQRzAVVlJ3BB4kcx78CAZQbUjVIxrFtd+OdrbmpHhEXG5VE4rTwHz
|
||||
wMRdFDw4jEgFj5dyRyRqsxYVEcfu3cQFPPv2ES8qHEbCYRzgsFZLvO+8Q7xKJXGDVoXCK46Ovob95YBW
|
||||
Ph/8+xwE/wSTyHi81OZVq9qsGs2Ye8sW4srPJy6JhDgTE4kzOpo4IyKIMyyMOLhcX9Py5R4lj0cPtAKs
|
||||
BBwwKfc7p174J5BEhHY9FIk6bBDaIRuiQkDFfsLDSbdU+pdBKPwe8e+BNDBD7vdNn6BYd+6stK5da7bP
|
||||
nz9TDujcoEAw1lJY+CyFz9dCHDubnDJjwltRccS5fr3TjurnlIMBYE5NJY8Nhq7SrCwREsz6xL9y4S4v
|
||||
b3Bt2uSyR0XNkDvQe9ouKu8HvaGh5FfQIxL5OgyG30qUStqmGUkm/3jKy0+48vLcs1XuiI8nL/Ly/rYl
|
||||
JfmovCcgN4JW+l8iGe8oKuoqzcyckSQob3CpVB47l+sXv9KWxYtJt0r1x9ns7HZjQYHNnJxMfoH0EXgA
|
||||
7oFm0CmTjRsNhs6Na9bQF+Tkq57xlJXVu9Rqz9Bs8kWLSG9BwcsqieQONlXnpaaWdul0z7rR+6C8CTSC
|
||||
m8Aol4+36/XGT7VaevCRIIRx6/WWoQULZq2cyveLxY0IrAT0IHm1OTmZT3Q6U2da2qT8B/Ad+BZ05OSM
|
||||
GXW6p4hdBiIZZ1FRt5vPn6vyuwiqCsj9Xyq6qXbDBkWnXm/6OS3NN1X+dUgIeZSdPXZPoxlEXC6IY9pL
|
||||
S7faNBqXC9Iplf95YBb5ZF+RpGbdunQcbO/D1avJ9YC8LT19/Iv8/BeqpKRPEDORAGNeY3HxSYtG43Eq
|
||||
FL5etfpljUzWhPlZ5VOTlGVliR+hHUbs+0mpHP9GpRqM5XAuY20zmGgRRohYKIx9rNd/3qfTOa7l5uLu
|
||||
C63BvARw6fp0eRCMyBslJe8+2bx58EFhoVMlFNJvgQ4kgggQEgykvV0ApEAd+J3z8Z8KxmuA3pr0zikA
|
||||
b4LJZ2FqYBigFdOPNf0NC679Fxi0OPr+XxiAJgwURph/AJfOQQebMR8TAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="TrayIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAACQAAMMOAADDDgAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACOMzL/jjMy/44zMv+OMzL/jjMy/44zMv9Ts2//U7Nv/1Ozb/9Ts2//U7Nv/1Oz
|
||||
b/891/H/Pdfx/z3X8f891/H/Pdfx/z3X8f8ukuD/LpLg/y6S4P8ukuD/LpLg/y6S4P8vOs7/LzrO/y86
|
||||
zv8vOs7/LzrO/y86zv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI8vLx+OMzL/jjMy/44zMv+OMzL/jjMy/4w4NOJTs2//U7Nv/1Oz
|
||||
b/9Ts2//U7Nv/1O0cuI91/H/Pdfx/z3X8f891/H/Pdfx/z3X8f8ukuD/LpLg/y6S4P8ukuD/LpLg/y6S
|
||||
4P8vOs7/LzrO/y86zv8vOs7/LzrO/y86zv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI0yMjeOMzL/jjMy/44zMv+OMzL/jjMy/4tD
|
||||
N9NTs2//U7Nv/1Ozb/9Ts2//U7Nv/1K1fNM91/H/Pdfx/z3X8f891/H/Pdfx/zzW8OkukuD/LpLg/y6S
|
||||
4P8ukuD/LpLg/y6R4PcvOs7/LzrO/y86zv8vOs7/LzrO/y86zuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIwzM0+OMzL/jjMy/44z
|
||||
Mv+OMzL/jjMy/4hRPcdTs2//U7Nv/1Ozb/9Ts2//U7Nv/1G4h8c91/H/Pdfx/z3X8f891/H/Pdfx/zzV
|
||||
8eIukuD/LpLg/y6S4P8ukuD/LpLg/y2R4OIvOs7/LzrO/y86zv8vOs7/LzrO/y46zd4AAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4z
|
||||
MZ6OMzL/jjMy/44zMv+OMzL/jjMy/4NiRMBTs2//U7Nv/1Ozb/9Ts2//U7Nv/067mMA91/H/Pdfx/z3X
|
||||
8f891/H/Pdfx/zzR78sukuD/LpLg/y6S4P8ukuD/LpLg/y2Q39cvOs7/LzrO/y86zv8vOs7/LzrO/y86
|
||||
ztYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAI0zMu6OMzL/jjMy/44zMv+OMzL/jjMy/26RXMdTs2//U7Nv/1Ozb/9Ts2//U7Nv/0vB
|
||||
rr491/H/Pdfx/z3X8f891/H/Pdfx/zjI7b8ukuD/LpLg/y6S4P8ukuD/LpLg/y2J3cUvOs7/LzrO/y86
|
||||
zv8vOs7/LzrO/y46zq4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAjzMzP44zMv+OMzL/jjMy/44zMv+OMzL/jjIx91SwbvZTs2//U7Nv/1Oz
|
||||
b/9Ts2//U7Nv/0XM1M491/H/Pdfx/z3X8f891/H/Pdfx/za66cAukuD/LpLg/y6S4P8ukuD/LpLg/y55
|
||||
2b4vOs7/LzrO/y86zv8vOs7/LzrO/y46zo4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjjIxro4zMv+OMzL/jjMy/44zMv+OMzL/iUw7y1Oz
|
||||
b/9Ts2//U7Nv/1Ozb/9Ts2//U7Nv7z3X8f891/H/Pdfx/z3X8f891/H/Pdfx/zCk49cukuD/LpLg/y6S
|
||||
4P8ukuD/LpLg/y1p1ccvOs7/LzrO/y86zv8vOs7/LzrO/y46zWcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPNC4vjjMy/44zMv+OMzL/jjMy/44z
|
||||
Mv+OMzL/dIdXwlOzb/9Ts2//U7Nv/1Ozb/9Ts2//T7qSwj3X8f891/H/Pdfx/z3X8f891/H/PNXx4i6S
|
||||
4P8ukuD/LpLg/y6S4P8ukuD/LpLg/y5N0OIvOs7/LzrO/y86zv8vOs7/LzrO/y07zDcAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNMjLOjjMy/44z
|
||||
Mv+OMzL/jjMy/44zMv+NNDLvWqpr6FOzb/9Ts2//U7Nv/1Ozb/9Ts2//RsnKxz3X8f891/H/Pdfx/z3X
|
||||
8f891/H/OcvtwC6S4P8ukuD/LpLg/y6S4P8ukuD/LZHg4i86zv8vOs7/LzrO/y86zv8vOs7/LzrO/y4+
|
||||
zw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4z
|
||||
MHeOMzL/jjMy/44zMv+OMzL/jjMy/44zMv95flG/U7Nv/1Ozb/9Ts2//U7Nv/1Ozb/9Ssm/3PdXt9j3X
|
||||
8f891/H/Pdfx/z3X8f891/H/M63myi6S4P8ukuD/LpLg/y6S4P8ukuD/Lobcwi86zv8vOs7/LzrO/y86
|
||||
zv8vOs7/LjnNzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAjDMzT44zMv+OMzL/jjMy/44zMv+OMzL/jjMy/441MulUsG72U7Nv/1Ozb/9Ts2//U7Nv/1Oz
|
||||
b/9PuI3FPdfx/z3X8f891/H/Pdfx/z3X8f881/HvLpTh9i6S4P8ukuD/LpLg/y6S4P8ukuD/LXDXwi86
|
||||
zv8vOs7/LzrO/y86zv8vOs7/LjrOjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACvhoQ4jzg39o4zMv+OMzL/jjMy/44zMv+OMzL/jjMy/3SHV8JTs2//U7Nv/1Oz
|
||||
b/9Ts2//U7Nv/1Ozb/9D0NzXPdfx/z3X8f891/H/Pdfx/z3X8f87zu7FLpLg/y6S4P8ukuD/LpLg/y6S
|
||||
4P8ukuD/Lk3Q4i86zv8vOs7/LzrO/y86zv8vOs7/LznMTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAALKPjmi5mpn4roaG/485OP+OMzL/jjMy/44zMv+OMzL/i0c5zlOz
|
||||
b/9Ts2//U7Nv/1Ozb/9Ts2//U7Nv/067mMA91/H/Pdfx/z3X8f891/H/Pdfx/z3X8f82uOjCLpLg/y6S
|
||||
4P8ukuD/LpLg/y6S4P8ujt/ULzrO/y86zv8vOs7/LzrO/y86zv8vOs7/Lj7PDwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtJKSkrmamv+5mpr/uZqa/66Ghv+POTj/jjMy/44z
|
||||
Mv+MODTiWqpr6FOzb/9Ts2//U7Nv/1Ozb/9Ts2//UrJv9z/U5+g91/H/Pdfx/z3X8f891/H/Pdfx/zzW
|
||||
8OkulOH2LpLg/y6S4P8ukuD/LpLg/y6S4P8ucdfFLzrO/y86zv8vOs7/LzrO/y86zv8uOs6+AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKPj1+4l5fguZqa/7mamv+5mpr/uZqa/7ma
|
||||
mv+uhob/jzk4/44yMfdkoGTXU7Nv/1Ozb/9Ts2//U7Nv/1Ozb/9Ts2//Tr2dvz3X8f891/H/Pdfx/z3X
|
||||
8f891/H/Pdfx/za46MIukuD/LpLg/y6S4P8ukuD/LpLg/y6R4PcvQ8/2LzrO/y86zv8vOs7/LzrO/y86
|
||||
zv8uOs1nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKd+fhuzkJBxtZKS2bmamv+5mpr/uZqa/7ma
|
||||
mv+5mpr/uZqa/7mamv+5mpr/roaG/3GTYMdTs2//U7Nv/1Ozb/9Ts2//U7Nv/1Ozb/9SsnHpP9Tn6D3X
|
||||
8f891/H/Pdfx/z3X8f891/H/PNXw1y6S4P8ukuD/LpLg/y6S4P8ukuD/LpLg/y6C278vOs7/LzrO/y86
|
||||
zv8vOs7/LzrO/y85zvYuPs8PAAAAAAAAAACzjY1Ns42NTbOQkHG0kpKSt5aWzLmamv+5mpr/uZqa/7ma
|
||||
mv+5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+7nZzzssOu2ZHGnf9WtHH/U7Nv/1Ozb/9Ts2//U7Nv/1Ky
|
||||
b/dFzNTOPdfx/z3X8f891/H/Pdfx/z3X8f891/H/NLDmxy6S4P8ukuD/LpLg/y6S4P8ukuD/LpHg9y5K
|
||||
0OgvOs7/LzrO/y86zv8vOs7/LzrO/y46zq4AAAAAAAAAAAAAAAC5mpr/uZqa/7mamv+5mpr/uZqa/7ma
|
||||
mv+5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+5mpr/uZqa/72hoOerya7mos2s/6LNrP+Rxp3/VrRx/1Oz
|
||||
b/9Ts2//U7Nv/0nFusA91/H/Pdfx/z3X8f891/H/Pdfx/z3X8f880vDOLpLg/y6S4P8ukuD/LpLg/y6S
|
||||
4P8ukuD/LoDbyS86zv8vOs7/LzrO/y86zv8vOs7/LzrO/y85zE8AAAAAAAAAAAAAAAC5mpr/uZqa/7ma
|
||||
mv+5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+5mpr/vaml2qbMrPOizaz/os2s/6LN
|
||||
rP+izaz/kcad/1a0cf9Ts2//Tr2dvz3X8f891/H/Pdfx/z3X8f891/H/Pdfx/z3X8f8wpOPXLpLg/y6S
|
||||
4P8ukuD/LpLg/y6S4P8ukODpLkDP9i86zv8vOs7/LzrO/y86zv8vOs7/LjnNzgAAAAAAAAAAAAAAAAAA
|
||||
AAC5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+5mpr/uZqa/72jouOyw67Zos2s/6LN
|
||||
rP+izaz/os2s/6LNrP+izaz/os2s/5HGnf9VuIbLPdfx/z3X8f891/H/Pdfx/z3X8f891/H/Pdfx/zjG
|
||||
7L4ukuD/LpLg/y6S4P8ukuD/LpLg/y6S4P8td9i/LzrO/y86zv8vOs7/LzrO/y86zv8vOs7/LznMTwAA
|
||||
AAAAAAAAAAAAAAAAAAC5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+8np7vtr6t1KLN
|
||||
rP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6vUvdeK3/H3Qtfx/z3X8f891/H/Pdfx/z3X
|
||||
8f891/H/O9Dvxy6S4P8ukuD/LpLg/y6S4P8ukuD/LpLg/y6Q4OsuQM/2LzrO/y86zv8vOs7/LzrO/y86
|
||||
zv8uOc3OAAAAAAAAAAAAAAAAAAAAAAAAAAC5mpr/uZqa/7mamv+5mpr/uZqa/7mamv+8oJ/qvLGp07LD
|
||||
rtmizaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/rNjL0Zzk9f+c5PX/ieD0/0LX
|
||||
8f891/H/Pdfx/z3X8f871O/eLpTh9i6S4P8ukuD/LpLg/y6S4P8ukuD/LpLg/y1p1ccvOs7/LzrO/y86
|
||||
zv8vOs7/LzrO/y86zv8vOcxPAAAAAAAAAAAAAAAAAAAAAAAAAAC+p6Tcvqek3L2vqNS6t6vSurms0a3H
|
||||
reOizaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6PNrfmp3dzVnOT1/5zk
|
||||
9f+c5PX/nOT1/4ng9P9C1/H/Pdfx/zzX8fAwnuLiLpLg/y6S4P8ukuD/LpLg/y6S4P8ukuD/Lo3e0C86
|
||||
zv8vOs7/LzrO/y86zv8vOs7/LzrO/y45zc4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACizaz/os2s/6LN
|
||||
rP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/pc6v76Xg
|
||||
5d+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+J4PT/Qdbw9zKr5dQukuD/LpLg/y6S4P8ukuD/LpLg/y6S
|
||||
4P8tkeDjLkPO7y86zv8vOs7/LzrO/y86zv8vOs7/LzrO/y46zy8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AACizaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6TP
|
||||
rvOr2tDRnePy+Jzk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+d4/T5j8nt2TST4P8ukuD/LpLg/y6S
|
||||
4P8ukuD/LpLg/y6R4PcuVdHkLzrO/y86zv8vOs7/LzrO/y86zv8vOs7/LjnOngAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACizaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LN
|
||||
rP+jza35rNjI0p/j8fOc5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5/k9e+hyu7jmbvq/4Wx
|
||||
5/80k+D/LpLg/y6S4P8ukuD/LpLg/y5o1cwvOs7/LzrO/y86zv8vOs7/LzrO/y86zv8uOc3uKTTJFwAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACizaz/os2s/6LNrP+izaz/os2s/6LNrP+izaz/os2s/6LN
|
||||
rP+izaz/ptCx6qvXxdOh4e3qnOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/ouP15JzD
|
||||
6/SZu+r/mbvq/5m76v+Fsef/NJPg/y6S4P8ukuD/LXvZxi86zv8vOs7/LzrO/y86zv8vOs7/LzrO/y86
|
||||
zv8uOM1HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACizaz/os2s/6LNrP+izaz/os2s/6LN
|
||||
rP+izaz/p9Cz56vZztKk4ejjnOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk
|
||||
9f+l4PTZmr3q+Jm76v+Zu+r/mbvq/5m76v+Zu+r/hbHn/zST4P8uiN3MLzrO/y86zv8vOs7/LzrO/y86
|
||||
zv8vOs7/LzrO/y84zG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACp0rjcqdK43KvW
|
||||
wtSr2c7Sq9rQ0aff5Nyh4e3qnOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk
|
||||
9f+c5PX/nOT1/6ba8teZu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/42z5941Rc/2LzrO/y86
|
||||
zv8vOs7/LzrO/y86zv8vOs7/LznOlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AACc5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk
|
||||
9f+c5PX/nOT1/5zk9f+l4fTbncPr75m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/o73p2Zqe
|
||||
3/iFiNr/NT/O/y86zv8vOs7/LzrO/y86zv8uOs6+HD2+BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACc5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk
|
||||
9f+c5PX/nOT1/5zk9f+c5PX/pOL13qHK7uOZu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+ltufVmZve/5mb3v+Zm97/hYja/zU/zv8vOs7/LzrO/y46zd4uPs8PAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACc5PX/nOT1/5zk9f+c5PX/nOT1/5zk9f+c5PX/nOT1/5zk
|
||||
9f+c5PX/nOT1/5zk9f+c5PX/nOT1/6Hj9Oeiz+/fmbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/nL3q86Ku5N6Zm97/mZve/5mb3v+Zm97/mZve/4WI2v81P87/LjnN7iw5zCcAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACc5PX/nOT1/5zk9f+c5PX/nOT1/5zk
|
||||
9f+c5PX/nOT1/5zk9f+c5PX/nOT1/6Hj9eun3vPSoszu4Jm76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+fvurnn6fh5pmb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Fh9n3LjjNRwAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACc5PX/nOT1/5zk
|
||||
9f+c5PX/nOT1/5zk9f+c5PX/nOT1/6Tk9OCn2PHSoMfs5pm76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+Zu+r/mbvq/6O/6tqcoN/zmZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5aY
|
||||
3fJ/gtlJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AACl4/XcpeP13KXj9dyl4/Xcp93z0afY8dKjze7cnMDr85m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+gv+rjoq7j3Jmb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb
|
||||
3v+Zm97/lJbc2X6A2SUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACZu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/nr7q6qWz5dWZm97/mZve/5mb3v+Zm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Sld2+aXDWEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5y96vOmuOfSmp7f+Jmb3v+Zm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/4mL2pYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZu+r/mbvq/5m76v+Zu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+dvervprrn0pyg3/OZm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+WmN34io3aZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZu+r/mbvq/5m7
|
||||
6v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+avOr5pL7q1qOw5NmZm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5OW3eyEh9o4AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AACZu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+Zu+r/mbvq/5m76v+iv+rcprrn0qKu49yZm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm974i43al4SLzwgAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACiv+rcor/q3KK/6tyiv+rcpL7q16a659KksuXXoKni45mb3v+Zm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5SW3cWEh9gvAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Vl93MjY/cTQAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZm97/mZve/5mb3v+Zm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/kJLcy42P
|
||||
3E0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZm97/mZve/5mb
|
||||
3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/lZfd7I2P
|
||||
26aEh9o4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AACZm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mJre7JOV
|
||||
3bCHitlUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACZm97/mZve/5mb3v+Zm97/mZve/5mb3v+Zm97/mZve/5mb3v+Ymt3ylJbdvo+R
|
||||
23mMj9oxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVl93MlZfdzJWX3cyVl93MlJbdxZGT25KPkdpxjY/cTYSL
|
||||
zwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//8AAAAAAAP//gAAAAAAA//+AAAAA
|
||||
AAD//4AAAAAAAP//gAAAAAAA//+AAAAAAAD//wAAAAAAAP//AAAAAAAA//4AAAAAAAD//gAAAAAAAP/8
|
||||
AAAAAQAA//gAAAABAAD/8AAAAAEAAP/gAAAAAQAA/8AAAAADAAD/AAAAAAMAAPgAAAAAAwAAAAAAAAAH
|
||||
AAAAAAAAAAcAAAAAAAAADwAAAAAAAAAPAAAAAAAAAB8AAAAAAAAAHwAAAAAAAAA/AAAAAAAAAD8AAAAA
|
||||
AAAAfwAAAAAAAAB/AAAAAAAAAP8AAAAAAAAB/wAAAAAAAAP/AAAAAAAAA/8AAAAAAAAH/wAAAAAAAA//
|
||||
AAAAAAAAH/8AAAAAAAA//wAAAAAAAH//AAAAAAAA//8AAAAAAAP//wAAAAAAB///AAAAAAAP//8AAAAA
|
||||
AB///wAAAAAAf///AAAAAAH///8AAAAAB////wAAAAAf////AAAAAP////8AAAAH/////wAAAH//////
|
||||
AAA=
|
||||
</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
|
||||
@@ -17,6 +17,7 @@ Public Class MainFrame
|
||||
Private MyView As FormsView
|
||||
Private ReadOnly _VideoDownloadingMode As Boolean = False
|
||||
Private MyChannels As ChannelViewForm
|
||||
Private MySavedPosts As DownloadSavedPostsForm
|
||||
Private _UFinit As Boolean = True
|
||||
Public Sub New()
|
||||
InitializeComponent()
|
||||
@@ -29,21 +30,24 @@ Public Class MainFrame
|
||||
If Args.ListExists(2) AndAlso Args(1) = "v" Then
|
||||
Using f As New VideosDownloaderForm : f.ShowDialog() : End Using
|
||||
_VideoDownloadingMode = True
|
||||
Else
|
||||
Downloader = New TDownloader
|
||||
End If
|
||||
End Sub
|
||||
Private Sub MainFrame_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
If _VideoDownloadingMode Then GoTo FormClosingInvoker
|
||||
Settings.DeleteCachPath()
|
||||
MainProgress = New Toolbars.MyProgress(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS) With {.DropCurrentProgressOnTotalChange = False, .Enabled = False}
|
||||
MainProgressInst = New Toolbars.MyProgress(Toolbar_BOTTOM, PR_INST, LBL_STATUS_INST) With {.DropCurrentProgressOnTotalChange = False, .Enabled = False}
|
||||
Downloader = New TDownloader
|
||||
InfoForm = New DownloadedInfoForm
|
||||
AddHandler Downloader.OnJobsChange, AddressOf Downloader_UpdateJobsCount
|
||||
AddHandler Downloader.OnDownloading, AddressOf Downloader_OnDownloading
|
||||
AddHandler Downloader.OnDownloadCountChange, AddressOf InfoForm.Downloader_OnDownloadCountChange
|
||||
AddHandler Downloader.SendNotification, AddressOf NotificationMessage
|
||||
Settings.LoadUsers()
|
||||
MyView = New FormsView(Me)
|
||||
MyView.ImportFromXML(Settings.Design)
|
||||
MyView.SetMeSize()
|
||||
MainProgress = New Toolbars.MyProgress(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS) With {.DropCurrentProgressOnTotalChange = False}
|
||||
If Settings.CloseToTray Then TrayIcon.Visible = True
|
||||
Dim gk$
|
||||
With LIST_PROFILES.Groups
|
||||
'Collections
|
||||
@@ -92,40 +96,80 @@ FormClosingInvoker:
|
||||
EndFunction:
|
||||
End Sub
|
||||
Private _CloseInvoked As Boolean = False
|
||||
Private _IgnoreTrayOptions As Boolean = False
|
||||
Private _IgnoreCloseConfirm As Boolean = False
|
||||
Private Async Sub MainFrame_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||
If Not _VideoDownloadingMode Then
|
||||
If _CloseInvoked Then GoTo CloseResume
|
||||
Dim ChannelsWorking As Func(Of Boolean) = Function() If(MyChannels?.Working, False)
|
||||
If (Not Downloader.Working And Not ChannelsWorking.Invoke) OrElse
|
||||
MsgBoxE({"Program still downloading something..." & vbNewLine &
|
||||
"Do you really want to stop downloading and exit of program?",
|
||||
"Downloading in progress"},
|
||||
MsgBoxStyle.Exclamation,,,
|
||||
{"Stop downloading and close", "Cancel"}) = 0 Then
|
||||
If Downloader.Working Then _CloseInvoked = True : Downloader.Stop() : Downloader.DownloadSavedPostsStop()
|
||||
If Downloader.SavedPostsDownloading Then _CloseInvoked = True : Downloader.DownloadSavedPostsStop()
|
||||
If ChannelsWorking.Invoke Then _CloseInvoked = True : MyChannels.Stop(False)
|
||||
If _CloseInvoked Then
|
||||
e.Cancel = True
|
||||
Await Task.Run(Sub()
|
||||
While Downloader.Working Or ChannelsWorking.Invoke Or Downloader.SavedPostsDownloading : Thread.Sleep(500) : End While
|
||||
End Sub)
|
||||
If Settings.CloseToTray And Not _IgnoreTrayOptions Then
|
||||
e.Cancel = True
|
||||
Hide()
|
||||
Else
|
||||
If Not _VideoDownloadingMode Then
|
||||
If CheckForClose(_IgnoreCloseConfirm) Then
|
||||
If _CloseInvoked Then GoTo CloseResume
|
||||
Dim ChannelsWorking As Func(Of Boolean) = Function() If(MyChannels?.Working, False)
|
||||
Dim SP_Working As Func(Of Boolean) = Function() If(MySavedPosts?.Working, False)
|
||||
If (Not Downloader.Working And Not ChannelsWorking.Invoke And Not SP_Working.Invoke) OrElse
|
||||
MsgBoxE({"Program still downloading something..." & vbNewLine &
|
||||
"Do you really want to stop downloading and exit of program?",
|
||||
"Downloading in progress"},
|
||||
MsgBoxStyle.Exclamation,,,
|
||||
{"Stop downloading and close", "Cancel"}) = 0 Then
|
||||
If Downloader.Working Then _CloseInvoked = True : Downloader.Stop()
|
||||
If ChannelsWorking.Invoke Then _CloseInvoked = True : MyChannels.Stop(False)
|
||||
If SP_Working.Invoke Then _CloseInvoked = True : MySavedPosts.Stop()
|
||||
If _CloseInvoked Then
|
||||
e.Cancel = True
|
||||
Await Task.Run(Sub()
|
||||
While Downloader.Working Or ChannelsWorking.Invoke Or SP_Working.Invoke : Thread.Sleep(500) : End While
|
||||
End Sub)
|
||||
End If
|
||||
Downloader.Dispose()
|
||||
InfoForm.Dispose()
|
||||
If Not MyChannels Is Nothing Then MyChannels.Dispose()
|
||||
If Not VideoDownloader Is Nothing Then VideoDownloader.Dispose()
|
||||
If Not MySavedPosts Is Nothing Then MySavedPosts.Dispose()
|
||||
MyView.Dispose(Settings.Design)
|
||||
Settings.Dispose()
|
||||
Else
|
||||
GoTo DropCloseParams
|
||||
End If
|
||||
Else
|
||||
GoTo DropCloseParams
|
||||
End If
|
||||
Downloader.Dispose()
|
||||
InfoForm.Dispose()
|
||||
If Not MyChannels Is Nothing Then MyChannels.Dispose()
|
||||
If Not VideoDownloader Is Nothing Then VideoDownloader.Dispose()
|
||||
MyView.Dispose(Settings.Design)
|
||||
Settings.Dispose()
|
||||
Else
|
||||
e.Cancel = True
|
||||
Exit Sub
|
||||
End If
|
||||
End If
|
||||
If Not MyMainLOG.IsEmptyString Then SaveLogToFile()
|
||||
If _CloseInvoked Then Close()
|
||||
GoTo CloseContinue
|
||||
DropCloseParams:
|
||||
e.Cancel = True
|
||||
_IgnoreTrayOptions = False
|
||||
_IgnoreCloseConfirm = False
|
||||
_CloseInvoked = False
|
||||
Exit Sub
|
||||
CloseContinue:
|
||||
If Not MyMainLOG.IsEmptyString Then SaveLogToFile()
|
||||
If _CloseInvoked Then Close()
|
||||
CloseResume:
|
||||
End If
|
||||
End Sub
|
||||
#Region "Tray"
|
||||
Private Sub TrayIcon_MouseClick(sender As Object, e As MouseEventArgs) Handles TrayIcon.MouseClick
|
||||
If e.Button = MouseButtons.Left Then
|
||||
If Visible Then Hide() Else Show()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub BTT_TRAY_SHOW_HIDE_Click(sender As Object, e As EventArgs) Handles BTT_TRAY_SHOW_HIDE.Click
|
||||
If Visible Then Hide() Else Show()
|
||||
End Sub
|
||||
Private Sub BTT_TRAY_CLOSE_Click(sender As Object, e As EventArgs) Handles BTT_TRAY_CLOSE.Click
|
||||
If CheckForClose(False) Then _IgnoreTrayOptions = True : _IgnoreCloseConfirm = True : Close()
|
||||
End Sub
|
||||
Private Function CheckForClose(ByVal _Ignore As Boolean) As Boolean
|
||||
If Settings.ExitConfirm And Not _Ignore Then
|
||||
Return MsgBoxE({"Do you want to close the program?", "Closing the program"}, MsgBoxStyle.YesNo) = MsgBoxResult.Yes
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
End Function
|
||||
#End Region
|
||||
Private Sub MainFrame_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||
Dim b As Boolean = True
|
||||
Select Case e.KeyCode
|
||||
@@ -262,6 +306,9 @@ CloseResume:
|
||||
Private Sub BTT_SETTINGS_INSTAGRAM_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS_INSTAGRAM.Click
|
||||
Using f As New SiteEditorForm(Sites.Instagram) : f.ShowDialog() : End Using
|
||||
End Sub
|
||||
Private Sub BTT_SETTINGS_REDGIFS_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS_REDGIFS.Click
|
||||
Using f As New SiteEditorForm(Sites.RedGifs) : f.ShowDialog() : End Using
|
||||
End Sub
|
||||
Private Sub BTT_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS.Click
|
||||
Dim mhl% = Settings.MaxLargeImageHeigh.Value
|
||||
Dim mhs% = Settings.MaxSmallImageHeigh.Value
|
||||
@@ -269,6 +316,7 @@ CloseResume:
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK Then
|
||||
If Not Settings.MaxLargeImageHeigh = mhl Or Not Settings.MaxSmallImageHeigh = mhs Then RefillList()
|
||||
TrayIcon.Visible = Settings.CloseToTray
|
||||
End If
|
||||
End Using
|
||||
End Sub
|
||||
@@ -356,11 +404,18 @@ CloseResume:
|
||||
If MyChannels Is Nothing Then
|
||||
MyChannels = New ChannelViewForm
|
||||
AddHandler MyChannels.OnUsersAdded, AddressOf OnUsersAddedHandler
|
||||
AddHandler MyChannels.OnDownloadDone, AddressOf NotificationMessage
|
||||
End If
|
||||
If MyChannels.Visible Then MyChannels.BringToFront() Else MyChannels.Show()
|
||||
End Sub
|
||||
Private Sub BTT_DOWN_SAVED_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_SAVED.Click
|
||||
Downloader.DownloadSavedPostsStart(Toolbar_BOTTOM, PR_SAVED)
|
||||
If MySavedPosts Is Nothing Then
|
||||
MySavedPosts = New DownloadSavedPostsForm
|
||||
AddHandler MySavedPosts.OnDownloadDone, AddressOf NotificationMessage
|
||||
End If
|
||||
With MySavedPosts
|
||||
If .Visible Then .BringToFront() Else .Show()
|
||||
End With
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download"
|
||||
@@ -507,6 +562,9 @@ CloseResume:
|
||||
Private Sub BTT_LOG_Click(sender As Object, e As EventArgs) Handles BTT_LOG.Click
|
||||
MyMainLOG_ShowForm(Settings.Design)
|
||||
End Sub
|
||||
Private Sub BTT_DONATE_Click(sender As Object, e As EventArgs) Handles BTT_DONATE.Click
|
||||
Try : Process.Start("https://ko-fi.com/andyprogram") : Catch : End Try
|
||||
End Sub
|
||||
#Region "List functions"
|
||||
Private _LatestSelected As Integer = -1
|
||||
Private Sub LIST_PROFILES_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_PROFILES.SelectedIndexChanged
|
||||
@@ -988,18 +1046,30 @@ ResumeDownloadingOperation:
|
||||
Friend Sub User_OnUserUpdated(ByVal User As IUserData)
|
||||
UserListUpdate(User, False)
|
||||
End Sub
|
||||
Private _LogVisible As Boolean = False
|
||||
Private Sub Downloader_UpdateJobsCount(ByVal TotalCount As Integer)
|
||||
Dim a As Action = Sub() LBL_JOBS_COUNT.Text = IIf(TotalCount = 0, String.Empty, $"[Jobs {TotalCount}]")
|
||||
Private _LogColorChanged As Boolean = False
|
||||
Private Sub Downloader_UpdateJobsCount(ByVal Site As Sites, ByVal TotalCount As Integer)
|
||||
Dim a As Action
|
||||
If Site = Sites.Instagram Then
|
||||
a = Sub() LBL_JOBS_INST_COUNT.Text = IIf(TotalCount = 0, String.Empty, $"[Jobs {TotalCount}]")
|
||||
Else
|
||||
a = Sub() LBL_JOBS_COUNT.Text = IIf(TotalCount = 0, String.Empty, $"[Jobs {TotalCount}]")
|
||||
End If
|
||||
If Toolbar_BOTTOM.InvokeRequired Then Toolbar_BOTTOM.Invoke(a) Else a.Invoke
|
||||
If Not _LogVisible AndAlso Not MyMainLOG.IsEmptyString Then
|
||||
If Not _LogColorChanged AndAlso Not MyMainLOG.IsEmptyString Then
|
||||
a = Sub() BTT_LOG.ControlChangeColor(False)
|
||||
If Toolbar_TOP.InvokeRequired Then Toolbar_TOP.Invoke(a) Else a.Invoke
|
||||
_LogVisible = True
|
||||
_LogColorChanged = True
|
||||
ElseIf _LogColorChanged And MyMainLOG.IsEmptyString Then
|
||||
a = Sub() BTT_LOG.ControlChangeColor(SystemColors.Control, SystemColors.ControlText)
|
||||
If Toolbar_TOP.InvokeRequired Then Toolbar_TOP.Invoke(a) Else a.Invoke
|
||||
_LogColorChanged = False
|
||||
End If
|
||||
End Sub
|
||||
Private Sub Downloader_OnDownloading(ByVal Value As Boolean)
|
||||
Dim a As Action = Sub() BTT_DOWN_STOP.Enabled = Value
|
||||
If Toolbar_TOP.InvokeRequired Then Toolbar_TOP.Invoke(a) Else a.Invoke
|
||||
End Sub
|
||||
Private Sub NotificationMessage(ByVal Message As String)
|
||||
If Settings.ShowNotifications Then TrayIcon.ShowBalloonTip(2000, TrayIcon.BalloonTipTitle, Message, ToolTipIcon.Info)
|
||||
End Sub
|
||||
End Class
|
||||
@@ -8,6 +8,7 @@
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Tools.WEB
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API
|
||||
Imports SCrawler.API.Base
|
||||
Friend Module MainMod
|
||||
@@ -44,11 +45,12 @@ Friend Module MainMod
|
||||
Friend Class NumberedFile : Inherits SFileNumbers
|
||||
Friend Sub New(ByVal f As SFile)
|
||||
FileName = f.Name
|
||||
NumberProvider = New ANumbers With {.FormatMode = ANumbers.Formats.NumberGroup, .GroupSize = 5}
|
||||
NumberProvider = New ANumbers With {.Format = ANumbers.Formats.NumberGroup, .GroupSize = 5}
|
||||
End Sub
|
||||
End Class
|
||||
#End Region
|
||||
Friend Property MainProgress As PersonalUtilities.Forms.Toolbars.MyProgress
|
||||
Friend Property MainProgress As MyProgress
|
||||
Friend Property MainProgressInst As MyProgress
|
||||
Friend Function GetLviGroupName(ByVal Site As Sites, ByVal Temp As Boolean, ByVal Fav As Boolean,
|
||||
ByVal IsCollection As Boolean, ByVal IsChannel As Boolean) As String
|
||||
Dim Opt$ = String.Empty
|
||||
@@ -71,6 +73,7 @@ Friend Module MainMod
|
||||
Reddit = 1
|
||||
Twitter = 2
|
||||
Instagram = 3
|
||||
RedGifs = 4
|
||||
End Enum
|
||||
Friend Structure UserInfo : Implements IComparable(Of UserInfo), IEquatable(Of UserInfo), ICloneable
|
||||
Friend Const Name_Site As String = "Site"
|
||||
@@ -208,7 +211,7 @@ Friend Module MainMod
|
||||
End Function
|
||||
Friend Function GetNewVideoURL() As String
|
||||
Dim b$ = GetCurrentBuffer()
|
||||
Dim URL$ = InputBox("Enter video URL:", "Download video by URL", b)
|
||||
Dim URL$ = InputBoxE("Enter video URL:", "Download video by URL", b)
|
||||
If Not URL.IsEmptyString Then Return URL Else Return String.Empty
|
||||
End Function
|
||||
Friend Sub DownloadVideoByURL()
|
||||
|
||||
@@ -10,7 +10,7 @@ Imports System.Runtime.InteropServices
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("Socials media data Crawler")>
|
||||
<Assembly: AssemblyDescription("Twitter and Reddit media crawler")>
|
||||
<Assembly: AssemblyDescription("Social networks media downloader")>
|
||||
<Assembly: AssemblyCompany("AndyProgram")>
|
||||
<Assembly: AssemblyProduct("SCrawler")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2022")>
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2.0.0.1")>
|
||||
<Assembly: AssemblyFileVersion("2.0.0.1")>
|
||||
<Assembly: AssemblyVersion("2.0.0.2")>
|
||||
<Assembly: AssemblyFileVersion("2.0.0.2")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
10
SCrawler/My Project/Resources.Designer.vb
generated
10
SCrawler/My Project/Resources.Designer.vb
generated
@@ -110,6 +110,16 @@ Namespace My.Resources
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
'''</summary>
|
||||
Friend ReadOnly Property HeartPic_32() As System.Drawing.Bitmap
|
||||
Get
|
||||
Dim obj As Object = ResourceManager.GetObject("HeartPic_32", resourceCulture)
|
||||
Return CType(obj,System.Drawing.Bitmap)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
'''</summary>
|
||||
|
||||
@@ -124,12 +124,18 @@
|
||||
<data name="PrevPIC2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\PrevPIC2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="StartPic_01_Green_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\StartPic_01_Green_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="PencilPic_01_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\PencilPic_01_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="NextPIC2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\NextPIC2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="BookmarkBlack_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\BookmarkBlack_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Folder_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\Folder_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
@@ -142,14 +148,11 @@
|
||||
<data name="TwitterIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Icons\TwitterIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SettingsPic_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\SettingsPic_16.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Delete" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\Delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="InfoPic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\InfoPic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="InstagramPic76" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\InstagramPic76.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="InstagramIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Icons\InstagramIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
@@ -157,18 +160,18 @@
|
||||
<data name="GlobeBlue_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\GlobeBlue_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="PicturePic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\PicturePic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="InfoPic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\InfoPic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Refresh" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\Refresh.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="PicturePic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\PicturePic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="RedditIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Icons\RedditIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="InstagramPic76" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\InstagramPic76.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Rainbow" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Icons\Rainbow.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
@@ -181,10 +184,10 @@
|
||||
<data name="DBPic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\DBPic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="StartPic_01_Green_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\StartPic_01_Green_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="SettingsPic_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\SettingsPic_16.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="BookmarkBlack_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\BookmarkBlack_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<data name="HeartPic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Pictures\HeartPic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -139,6 +139,7 @@
|
||||
<Compile Include="API\Base\UserDataBase.vb" />
|
||||
<Compile Include="API\Imgur\Envir.vb" />
|
||||
<Compile Include="API\Instagram\Declarations.vb" />
|
||||
<Compile Include="API\Instagram\ProfileSaved.vb" />
|
||||
<Compile Include="API\Instagram\UserData.vb" />
|
||||
<Compile Include="API\Reddit\Channel.vb" />
|
||||
<Compile Include="API\Reddit\ChannelsCollection.vb" />
|
||||
@@ -146,9 +147,17 @@
|
||||
<Compile Include="API\Reddit\M3U8.vb" />
|
||||
<Compile Include="API\Reddit\ProfileSaved.vb" />
|
||||
<Compile Include="API\Reddit\UserData.vb" />
|
||||
<Compile Include="API\Redgifs\Declarations.vb" />
|
||||
<Compile Include="API\Redgifs\UserData.vb" />
|
||||
<Compile Include="API\Twitter\Declarations.vb" />
|
||||
<Compile Include="API\Twitter\UserData.vb" />
|
||||
<Compile Include="API\UserDataBind.vb" />
|
||||
<Compile Include="Channels\ChannelsStatsForm.Designer.vb">
|
||||
<DependentUpon>ChannelsStatsForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Channels\ChannelsStatsForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Channels\ChannelViewForm.Designer.vb">
|
||||
<DependentUpon>ChannelViewForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
@@ -161,6 +170,12 @@
|
||||
<Compile Include="DownloadedInfoForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DownloadSavedPostsForm.Designer.vb">
|
||||
<DependentUpon>DownloadSavedPostsForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="DownloadSavedPostsForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Editors\CollectionEditorForm.Designer.vb">
|
||||
<DependentUpon>CollectionEditorForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
@@ -179,6 +194,9 @@
|
||||
<Compile Include="Editors\LabelsForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Editors\SiteDefaults.vb">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Editors\SiteSelectionForm.Designer.vb">
|
||||
<DependentUpon>SiteSelectionForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
@@ -233,12 +251,18 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Channels\ChannelsStatsForm.resx">
|
||||
<DependentUpon>ChannelsStatsForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Channels\ChannelViewForm.resx">
|
||||
<DependentUpon>ChannelViewForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="DownloadedInfoForm.resx">
|
||||
<DependentUpon>DownloadedInfoForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="DownloadSavedPostsForm.resx">
|
||||
<DependentUpon>DownloadSavedPostsForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Editors\CollectionEditorForm.resx">
|
||||
<DependentUpon>CollectionEditorForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@@ -296,6 +320,7 @@
|
||||
<None Include="Content\Pictures\TwitterPic400.png" />
|
||||
<None Include="Content\Pictures\InstagramPic76.png" />
|
||||
<None Include="Content\Pictures\BookmarkBlack_16.png" />
|
||||
<None Include="Content\Pictures\HeartPic_32.png" />
|
||||
<Content Include="ffmpeg.exe">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -61,7 +61,8 @@ Friend Class SettingsCLS : Implements IDisposable
|
||||
MySites = New Dictionary(Of Sites, SiteSettings) From {
|
||||
{Sites.Reddit, New SiteSettings(Sites.Reddit, MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)},
|
||||
{Sites.Twitter, New SiteSettings(Sites.Twitter, MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)},
|
||||
{Sites.Instagram, New SiteSettings(Sites.Instagram, MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)}
|
||||
{Sites.Instagram, New SiteSettings(Sites.Instagram, MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)},
|
||||
{Sites.RedGifs, New SiteSettings(Sites.RedGifs, MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)}
|
||||
}
|
||||
MySites(Sites.Reddit).Responser.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
||||
|
||||
@@ -120,7 +121,12 @@ Friend Class SettingsCLS : Implements IDisposable
|
||||
ShowNewVersionNotification = New XMLValue(Of Boolean)("ShowNewVersionNotification", True, MyXML)
|
||||
LatestVersion = New XMLValue(Of String)("LatestVersion", String.Empty, MyXML)
|
||||
|
||||
ExitConfirm = New XMLValue(Of Boolean)("ExitConfirm", True, MyXML)
|
||||
CloseToTray = New XMLValue(Of Boolean)("CloseToTray", True, MyXML)
|
||||
ShowNotifications = New XMLValue(Of Boolean)("ShowNotifications", True, MyXML)
|
||||
|
||||
If MyXML.ChangesDetected Then MyXML.Sort() : MyXML.UpdateData()
|
||||
|
||||
Labels = New LabelsKeeper
|
||||
If Not LatestSelectedLabels.IsEmptyString Then Labels.CurrentSelection.ListAddList(LatestSelectedLabels.Value.StringToList(Of String, List(Of String))("|"))
|
||||
If BlackListFile.Exists Then
|
||||
@@ -253,6 +259,10 @@ Friend Class SettingsCLS : Implements IDisposable
|
||||
If BlackListFile.Exists Then BlackListFile.Delete()
|
||||
End If
|
||||
End Sub
|
||||
Friend Sub DeleteCachPath()
|
||||
If Reddit.ChannelsCollection.ChannelsPathCache.Exists(SFO.Path, False) Then _
|
||||
Reddit.ChannelsCollection.ChannelsPathCache.Delete(SFO.Path, False, False, EDP.None)
|
||||
End Sub
|
||||
Friend Overloads Function UserExists(ByVal s As Sites, ByVal UserID As String) As Boolean
|
||||
Dim UserFinderBase As Predicate(Of IUserData) = Function(user) user.Site = s And user.Name = UserID
|
||||
Dim UserFinder As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
|
||||
@@ -369,6 +379,11 @@ Friend Class SettingsCLS : Implements IDisposable
|
||||
Friend ReadOnly Property ShowNewVersionNotification As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property LatestVersion As XMLValue(Of String)
|
||||
#End Region
|
||||
#Region "Other program properties"
|
||||
Friend ReadOnly Property ExitConfirm As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property CloseToTray As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property ShowNotifications As XMLValue(Of Boolean)
|
||||
#End Region
|
||||
#Region "IDisposable Support"
|
||||
Private disposedValue As Boolean = False
|
||||
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||
@@ -377,8 +392,7 @@ Friend Class SettingsCLS : Implements IDisposable
|
||||
If UserListUpdateRequired Then UpdateUsersList()
|
||||
If Not Channels Is Nothing Then
|
||||
Channels.Dispose()
|
||||
If Reddit.ChannelsCollection.ChannelsPathCache.Exists(SFO.Path, False) Then _
|
||||
Reddit.ChannelsCollection.ChannelsPathCache.Delete(SFO.Path, False, False, EDP.None)
|
||||
DeleteCachPath()
|
||||
End If
|
||||
For Each kv In MySites : kv.Value.Dispose() : Next
|
||||
MySites.Clear()
|
||||
|
||||
@@ -7,102 +7,206 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Threading
|
||||
Imports EOptions = PersonalUtilities.Forms.Toolbars.MyProgress.EnableOptions
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports EOptions = PersonalUtilities.Forms.Toolbars.IMyProgress.EnableOptions
|
||||
Imports SCrawler.API
|
||||
Imports SCrawler.API.Base
|
||||
Friend Class TDownloader : Implements IDisposable
|
||||
Friend Event OnJobsChange(ByVal JobsCount As Integer)
|
||||
Friend Event OnJobsChange(ByVal Site As Sites, ByVal JobsCount As Integer)
|
||||
Friend Event OnDownloadCountChange()
|
||||
Friend Event OnDownloading(ByVal Value As Boolean)
|
||||
Private TokenSource As CancellationTokenSource
|
||||
Private ReadOnly Items As List(Of IUserData)
|
||||
Friend Event SendNotification(ByVal Message As String)
|
||||
Friend ReadOnly Property Downloaded As List(Of IUserData)
|
||||
Private ReadOnly NProv As IFormatProvider
|
||||
Private _Working As Boolean = False
|
||||
Friend ReadOnly Property Working As Boolean
|
||||
Friend ReadOnly Property Working(Optional ByVal Site As Sites = Sites.Undefined) As Boolean
|
||||
Get
|
||||
Return _Working
|
||||
If Site = Sites.Instagram Then
|
||||
Return JobInst.Working
|
||||
Else
|
||||
Return JobDefault.Working Or JobInst.Working
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Private DThread As Thread
|
||||
Friend ReadOnly Property Count As Integer
|
||||
Get
|
||||
Return Items.Count
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub New()
|
||||
Items = New List(Of IUserData)
|
||||
Downloaded = New List(Of IUserData)
|
||||
NProv = New ANumbers(ANumbers.Modes.USA) With {
|
||||
.FormatMode = ANumbers.Formats.Number,
|
||||
.GroupSize = 3,
|
||||
.GroupSeparator = ANumbers.DefaultGroupSeparator,
|
||||
.DecimalDigits = 0
|
||||
}
|
||||
End Sub
|
||||
Friend Sub [Start]()
|
||||
If Not _Working AndAlso Count > 0 AndAlso Not If(DThread?.IsAlive, False) Then
|
||||
DThread = New Thread(New ThreadStart(AddressOf StartDownloading))
|
||||
DThread.SetApartmentState(ApartmentState.MTA)
|
||||
DThread.Start()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub StartDownloading()
|
||||
Dim Token As CancellationToken
|
||||
RaiseEvent OnDownloading(True)
|
||||
Try
|
||||
_Working = True
|
||||
Friend Property InstagramSavedPostsDownloading As Boolean = False
|
||||
#Region "Jobs"
|
||||
Friend Structure Job
|
||||
Friend Site As Sites
|
||||
Private TokenSource As CancellationTokenSource
|
||||
Private Token As CancellationToken
|
||||
Private [Thread] As Thread
|
||||
Private _Working As Boolean
|
||||
Friend ReadOnly Items As List(Of IUserData)
|
||||
Friend ReadOnly Property Count As Integer
|
||||
Get
|
||||
Return Items.Count
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property Working As Boolean
|
||||
Get
|
||||
Return _Working OrElse If(Thread?.IsAlive, False)
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Progress As MyProgress
|
||||
Friend Sub New(ByRef _Progress As MyProgress)
|
||||
Progress = _Progress
|
||||
Items = New List(Of IUserData)
|
||||
End Sub
|
||||
Public Shared Widening Operator CType(ByVal j As Job) As CancellationToken
|
||||
Return j.Token
|
||||
End Operator
|
||||
Public Shared Widening Operator CType(ByVal j As Job) As Boolean
|
||||
Return j.Working
|
||||
End Operator
|
||||
Public Shared Operator And(ByVal x As Job, ByVal y As Job) As Boolean
|
||||
Return x.Working And y.Working
|
||||
End Operator
|
||||
Public Shared Operator And(ByVal x As Job, ByVal y As Boolean) As Boolean
|
||||
Return x.Working And y
|
||||
End Operator
|
||||
Public Shared Operator And(ByVal x As Boolean, ByVal y As Job) As Boolean
|
||||
Return x And y.Working
|
||||
End Operator
|
||||
Public Shared Operator Or(ByVal x As Job, ByVal y As Job) As Boolean
|
||||
Return x.Working Or y.Working
|
||||
End Operator
|
||||
Public Shared Operator Or(ByVal x As Job, ByVal y As Boolean) As Boolean
|
||||
Return x.Working Or y
|
||||
End Operator
|
||||
Public Shared Operator Or(ByVal x As Boolean, ByVal y As Job) As Boolean
|
||||
Return x Or y.Working
|
||||
End Operator
|
||||
Public Shared Operator Not(ByVal j As Job) As Boolean
|
||||
Return Not j.Working
|
||||
End Operator
|
||||
Friend Sub ThrowIfCancellationRequested()
|
||||
Token.ThrowIfCancellationRequested()
|
||||
End Sub
|
||||
Friend ReadOnly Property IsCancellationRequested As Boolean
|
||||
Get
|
||||
Return Token.IsCancellationRequested
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property IsInstagram As Boolean
|
||||
Get
|
||||
Return Site = Sites.Instagram
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub [Start](ByVal [ThreadStart] As ThreadStart)
|
||||
Thread = New Thread(ThreadStart) With {.IsBackground = True}
|
||||
Thread.SetApartmentState(ApartmentState.MTA)
|
||||
Thread.Start()
|
||||
End Sub
|
||||
Friend Sub [Start]()
|
||||
TokenSource = New CancellationTokenSource
|
||||
Token = TokenSource.Token
|
||||
MainProgress.TotalCount = 0
|
||||
MainProgress.CurrentCounter = 0
|
||||
Do While Count > 0
|
||||
Token.ThrowIfCancellationRequested()
|
||||
UpdateJobsLabel()
|
||||
DownloadData(Token)
|
||||
Token.ThrowIfCancellationRequested()
|
||||
Thread.Sleep(500)
|
||||
Loop
|
||||
MainProgress.InformationTemporary = "All data downloaded"
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
MainProgress.InformationTemporary = "Downloading canceled"
|
||||
Catch ex As Exception
|
||||
MainProgress.InformationTemporary = "Downloading error"
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "TDownloader.Start")
|
||||
Finally
|
||||
_Working = True
|
||||
End Sub
|
||||
Friend Sub [Stop]()
|
||||
If Not TokenSource Is Nothing Then TokenSource.Cancel()
|
||||
End Sub
|
||||
Friend Sub Stopped()
|
||||
_Working = False
|
||||
TokenSource = Nothing
|
||||
UpdateJobsLabel()
|
||||
If Settings(Sites.Instagram).InstaHashUpdateRequired Then MyMainLOG = "Check your Instagram credentials"
|
||||
Try
|
||||
If Not Thread Is Nothing Then
|
||||
If Thread.IsAlive Then Thread.Abort()
|
||||
Thread = Nothing
|
||||
End If
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
End Sub
|
||||
End Structure
|
||||
Private JobDefault As Job
|
||||
Private JobInst As Job
|
||||
#End Region
|
||||
Friend Sub New()
|
||||
Downloaded = New List(Of IUserData)
|
||||
NProv = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||
JobDefault = New Job(MainProgress)
|
||||
JobInst = New Job(MainProgressInst) With {.Site = Sites.Instagram}
|
||||
End Sub
|
||||
Friend Sub [Start]()
|
||||
If Not JobDefault.Working And JobDefault.Count > 0 Then JobDefault.Start(New ThreadStart(Sub() StartDownloading(JobDefault)))
|
||||
If Not JobInst.Working And JobInst.Count > 0 And Not InstagramSavedPostsDownloading Then _
|
||||
JobInst.Start(New ThreadStart(Sub() StartDownloading(JobInst)))
|
||||
End Sub
|
||||
Private Sub StartDownloading(ByRef _Job As Job)
|
||||
RaiseEvent OnDownloading(True)
|
||||
Dim isInst As Boolean = _Job.IsInstagram
|
||||
Dim pt As Func(Of String, String) = Function(ByVal t As String) As String
|
||||
Dim _t$ = If(isInst, $"Instagram {Left(t, 1).ToLower}{Right(t, t.Length - 1)}", t)
|
||||
RaiseEvent SendNotification(_t)
|
||||
Return _t
|
||||
End Function
|
||||
Try
|
||||
_Job.Start()
|
||||
_Job.Progress.TotalCount = 0
|
||||
_Job.Progress.CurrentCounter = 0
|
||||
_Job.Progress.Enabled = True
|
||||
Do While _Job.Count > 0
|
||||
_Job.ThrowIfCancellationRequested()
|
||||
UpdateJobsLabel(_Job)
|
||||
DownloadData(_Job, _Job)
|
||||
_Job.ThrowIfCancellationRequested()
|
||||
Thread.Sleep(500)
|
||||
Loop
|
||||
_Job.Progress.InformationTemporary = pt("All data downloaded")
|
||||
Catch oex As OperationCanceledException When _Job.IsCancellationRequested
|
||||
_Job.Progress.InformationTemporary = pt("Downloading canceled")
|
||||
Catch ex As Exception
|
||||
_Job.Progress.InformationTemporary = pt("Downloading error")
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "TDownloader.Start")
|
||||
Finally
|
||||
_Job.Stopped()
|
||||
UpdateJobsLabel(_Job)
|
||||
If _Job.Site = Sites.Instagram Then
|
||||
Settings(Sites.Instagram).InstagramLastDownloadDate.Value = Now
|
||||
If Settings(Sites.Instagram).InstaHashUpdateRequired Then MyMainLOG = "Check your Instagram credentials"
|
||||
End If
|
||||
_Job.Progress.Enabled(EOptions.ProgressBar) = False
|
||||
RaiseEvent OnDownloading(False)
|
||||
End Try
|
||||
End Sub
|
||||
Friend Sub [Stop]()
|
||||
If _Working Then TokenSource.Cancel()
|
||||
If JobDefault.Working Then JobDefault.Stop()
|
||||
If JobInst.Working Then JobInst.Stop()
|
||||
End Sub
|
||||
Private Sub UpdateJobsLabel()
|
||||
RaiseEvent OnJobsChange(Count)
|
||||
Private Overloads Sub UpdateJobsLabel()
|
||||
UpdateJobsLabel(JobDefault)
|
||||
UpdateJobsLabel(JobInst)
|
||||
End Sub
|
||||
Private _CurrentDownloadingTasks As Integer = 0
|
||||
Private Sub DownloadData(ByVal Token As CancellationToken)
|
||||
Private Overloads Sub UpdateJobsLabel(ByVal _Job As Job)
|
||||
RaiseEvent OnJobsChange(_Job.Site, _Job.Count)
|
||||
End Sub
|
||||
Private _InstagramNextWNM As Instagram.UserData.WNM = Instagram.UserData.WNM.Notify
|
||||
Private Sub DownloadData(ByRef _Job As Job, ByVal Token As CancellationToken)
|
||||
Try
|
||||
If Items.Count > 0 Then
|
||||
If _Job.Count > 0 Then
|
||||
Const nf As ANumbers.Formats = ANumbers.Formats.Number
|
||||
Dim t As New List(Of Task)
|
||||
Dim i% = -1
|
||||
Dim j% = Settings.MaxUsersJobsCount - 1
|
||||
Dim limit% = IIf(_Job.Site = Sites.Instagram, 1, j)
|
||||
Dim Keys As New List(Of String)
|
||||
Dim h As Boolean = False
|
||||
Dim InstaReady As Boolean = Settings(Sites.Instagram).InstagramReadyForDownload
|
||||
For Each _Item As IUserData In Items
|
||||
For Each _Item As IUserData In _Job.Items
|
||||
If Not _Item.Disposed Then
|
||||
Keys.Add(_Item.LVIKey)
|
||||
If Not _Item.Site = Sites.Instagram Or InstaReady Then
|
||||
If _Item.Site = Sites.Instagram Then h = True : Settings(Sites.Instagram).InstagramTooManyRequestsReadyForCatch = True
|
||||
Token.ThrowIfCancellationRequested()
|
||||
If _Item.Site = Sites.Instagram Then
|
||||
h = True
|
||||
With DirectCast(_Item, Instagram.UserData)
|
||||
.WaitNotificationMode = _InstagramNextWNM
|
||||
If Settings(Sites.Instagram).InstagramLastDownloadDate.Value < Now.AddMinutes(60) Then
|
||||
.RequestsCount = Settings(Sites.Instagram).InstagramLastRequestsCount
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
_Job.ThrowIfCancellationRequested()
|
||||
t.Add(Task.Run(Sub() _Item.DownloadData(Token)))
|
||||
i += 1
|
||||
If i >= j Then Exit For
|
||||
If i >= limit Then Exit For
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
@@ -112,38 +216,46 @@ Friend Class TDownloader : Implements IDisposable
|
||||
If .InstaHash.IsEmptyString Or .InstaHashUpdateRequired Then .GatherInstaHash()
|
||||
End With
|
||||
End If
|
||||
_CurrentDownloadingTasks = t.Count
|
||||
With MainProgress
|
||||
With _Job.Progress
|
||||
.Enabled(EOptions.All) = True
|
||||
.Information = $"Downloading {_CurrentDownloadingTasks.NumToString(nf, NProv)}/{Items.Count.NumToString(nf, NProv)} profiles' data"
|
||||
.Information = IIf(_Job.IsInstagram, "Instagram d", "D")
|
||||
.Information &= $"ownloading {t.Count.NumToString(nf, NProv)}/{_Job.Items.Count.NumToString(nf, NProv)} profiles' data"
|
||||
.InformationTemporary = .Information
|
||||
End With
|
||||
If t.Count > 0 Then Task.WaitAll(t.ToArray)
|
||||
Dim dcc As Boolean = False
|
||||
If Keys.Count > 0 Then
|
||||
For Each k$ In Keys
|
||||
i = Items.FindIndex(Function(ii) ii.LVIKey = k)
|
||||
i = _Job.Items.FindIndex(Function(ii) ii.LVIKey = k)
|
||||
If i >= 0 Then
|
||||
With Items(i)
|
||||
With _Job.Items(i)
|
||||
If _Job.Site = Sites.Instagram Then
|
||||
With DirectCast(.Self, Instagram.UserData)
|
||||
_InstagramNextWNM = .WaitNotificationMode
|
||||
If _InstagramNextWNM = Instagram.UserData.WNM.SkipTemp Or _InstagramNextWNM = Instagram.UserData.WNM.SkipCurrent Then _
|
||||
_InstagramNextWNM = Instagram.UserData.WNM.Notify
|
||||
Settings(Sites.Instagram).InstagramLastRequestsCount.Value = .RequestsCount
|
||||
End With
|
||||
End If
|
||||
If Not .Disposed AndAlso Not .IsCollection AndAlso .DownloadedTotal(False) > 0 Then
|
||||
If Not Downloaded.Contains(.Self) Then Downloaded.Add(GetUserFromMainCollection(.Self))
|
||||
dcc = True
|
||||
End If
|
||||
End With
|
||||
Items.RemoveAt(i)
|
||||
_Job.Items.RemoveAt(i)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
Keys.Clear()
|
||||
Items.RemoveAll(Function(ii) ii.Disposed)
|
||||
_Job.Items.RemoveAll(Function(ii) ii.Disposed)
|
||||
If dcc Then Downloaded.RemoveAll(Function(u) u Is Nothing)
|
||||
If dcc And Downloaded.Count > 0 Then RaiseEvent OnDownloadCountChange()
|
||||
t.Clear()
|
||||
End If
|
||||
End If
|
||||
Catch aoex As ArgumentOutOfRangeException
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, aoex, $"TDownloader.DownloadData: index out of range ({Count})")
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, aoex, $"TDownloader.DownloadData: index out of range ({_Job.Count})")
|
||||
Catch oex As OperationCanceledException When _Job.IsCancellationRequested
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "TDownloader.DownloadData")
|
||||
Finally
|
||||
@@ -151,7 +263,7 @@ Friend Class TDownloader : Implements IDisposable
|
||||
Task.WaitAll(Task.Run(Sub()
|
||||
While Settings.UserListUpdateRequired : Settings.UpdateUsersList() : End While
|
||||
End Sub))
|
||||
MainProgress.Enabled(EOptions.ProgressBar) = False
|
||||
If _Job.Site = Sites.Instagram Then Settings(Sites.Instagram).InstagramLastDownloadDate.Value = Now
|
||||
End Try
|
||||
End Sub
|
||||
Private Function GetUserFromMainCollection(ByVal User As IUserData) As IUserData
|
||||
@@ -178,50 +290,37 @@ Friend Class TDownloader : Implements IDisposable
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
#Region "Saved posts downloading"
|
||||
Friend ReadOnly Property SavedPostsDownloading As Boolean
|
||||
Get
|
||||
Return If(_SavedPostsThread?.IsAlive, False)
|
||||
End Get
|
||||
End Property
|
||||
Private _SavedPostsThread As Thread
|
||||
Friend Sub DownloadSavedPostsStart(ByVal Toolbar As StatusStrip, ByVal PR As ToolStripProgressBar)
|
||||
If Not SavedPostsDownloading Then
|
||||
If Settings(Sites.Reddit).SavedPostsUserName.IsEmptyString Then
|
||||
MsgBoxE($"Username of saved posts not set{vbNewLine}Operation canceled", MsgBoxStyle.Critical)
|
||||
Private Sub AddItem(ByVal Item As IUserData, ByVal _UpdateJobsLabel As Boolean)
|
||||
If Not Contains(Item) Then
|
||||
If Item.IsCollection Then
|
||||
Item.DownloadData(Nothing)
|
||||
ElseIf Item.Site = Sites.Instagram Then
|
||||
JobInst.Items.Add(Item)
|
||||
If _UpdateJobsLabel Then UpdateJobsLabel(JobInst)
|
||||
Else
|
||||
_SavedPostsThread = New Thread(New ThreadStart(Sub() Reddit.ProfileSaved.Download(Toolbar, PR)))
|
||||
_SavedPostsThread.SetApartmentState(ApartmentState.MTA)
|
||||
_SavedPostsThread.Start()
|
||||
JobDefault.Items.Add(Item)
|
||||
If _UpdateJobsLabel Then UpdateJobsLabel(JobDefault)
|
||||
End If
|
||||
Else
|
||||
MsgBoxE("Saved posts are already downloading", MsgBoxStyle.Exclamation)
|
||||
End If
|
||||
End Sub
|
||||
Friend Sub DownloadSavedPostsStop()
|
||||
Try
|
||||
If SavedPostsDownloading Then _SavedPostsThread.Abort()
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
End Sub
|
||||
#End Region
|
||||
Friend Sub Add(ByVal Item As IUserData)
|
||||
If Not Items.Contains(Item) Then
|
||||
If Item.IsCollection Then Item.DownloadData(Nothing) Else Items.Add(Item)
|
||||
UpdateJobsLabel()
|
||||
End If
|
||||
If Items.Count > 0 Then Start()
|
||||
AddItem(Item, True)
|
||||
If JobDefault.Count > 0 Or JobInst.Count > 0 Then Start()
|
||||
End Sub
|
||||
Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData))
|
||||
If _Items.ListExists Then
|
||||
For i% = 0 To _Items.Count - 1
|
||||
'If i = 5 Then UpdateJobsLabel() : Start()
|
||||
If _Items(i).IsCollection Then _Items(i).DownloadData(Nothing) Else Items.Add(_Items(i))
|
||||
Next
|
||||
For i% = 0 To _Items.Count - 1 : AddItem(_Items(i), False) : Next
|
||||
UpdateJobsLabel()
|
||||
End If
|
||||
If Items.Count > 0 Then Start()
|
||||
If JobDefault.Count > 0 Or JobInst.Count > 0 Then Start()
|
||||
End Sub
|
||||
Private Function Contains(ByVal _Item As IUserData)
|
||||
If _Item.Site = Sites.Instagram Then
|
||||
Return JobInst.Items.Contains(_Item)
|
||||
Else
|
||||
Return JobDefault.Items.Contains(_Item)
|
||||
End If
|
||||
End Function
|
||||
Friend Sub UserRemove(ByVal _Item As IUserData)
|
||||
If Downloaded.Count > 0 AndAlso Downloaded.Contains(_Item) Then Downloaded.Remove(_Item) : RaiseEvent OnDownloadCountChange()
|
||||
End Sub
|
||||
@@ -231,7 +330,8 @@ Friend Class TDownloader : Implements IDisposable
|
||||
If Not disposedValue Then
|
||||
If disposing Then
|
||||
[Stop]()
|
||||
Items.Clear()
|
||||
JobDefault.Items.Clear()
|
||||
JobInst.Items.Clear()
|
||||
Downloaded.Clear()
|
||||
End If
|
||||
disposedValue = True
|
||||
|
||||
Reference in New Issue
Block a user