From 938042ea9eec0a151481e74177c577ea7cb4ea4b Mon Sep 17 00:00:00 2001 From: Andy <88590076+AAndyProgram@users.noreply.github.com> Date: Mon, 5 Jun 2023 19:36:35 +0300 Subject: [PATCH] 2023.6.5.0 YT settings: removed property 'ItemsListLimit', add property 'ReplaceModificationDate' YT.MediaItem: fix 'Pending' YT.VideoListForm: add 'Shift' to add without downloading; add 'F5' hot key to start download; remove list items limit; fix item 'Pending', fixed items queue UserDataBase: add 'IconBannerDownloaded' properties; add 'HOST.Available' check to 'DownloadSingleObject'; update file deletion in 'DownloadContentDefault'; add truncating '_TempPostsList' if number of ids > 1000 Instagram: add authorization headers Mastodon: implement 'DownloadIconBanner'; update 'ReparseMissing' function Reddit: implement 'DownloadIconBanner' Twitter: implement 'DownloadIconBanner'; update parsers to parse posts with two videos; implement gallery-dl for all function; remove headers from settings Download.DownloadProgress: remove main progress perform when downloading saved posts VideoDownloaderForm: bind the 'BTT_ADD_URLS_ARR' button to the 'BTT_ADD_KeyClick' function UsersInfoForm: add folder opening on double click on an item ListImagesLoader: fix refill bug when the number of filtered profiles = 0 TrayIcon: add standalone downloader to context menu DownloadableMediaHost: fix a bug when not downloaded videos do not appear in the list when loading the program --- Changelog.md | 19 + .../SettingsGlobalDownloading.png | Bin 18025 -> 19268 bytes ProgramScreenshots/SettingsSiteInstagram.png | Bin 28106 -> 38269 bytes ProgramScreenshots/SettingsSiteTwitter.png | Bin 19424 -> 17594 bytes SCrawler.YouTube/Base/YouTubeSettings.vb | 6 +- SCrawler.YouTube/Downloader/MediaItem.vb | 3 + .../Downloader/VideoListForm.Designer.vb | 12 +- .../Downloader/VideoListForm.resx | 330 +++++------ SCrawler.YouTube/Downloader/VideoListForm.vb | 152 +++--- SCrawler.YouTube/My Project/AssemblyInfo.vb | 4 +- .../Objects/YouTubeMediaContainerBase.vb | 4 +- .../My Project/AssemblyInfo.vb | 4 +- SCrawler/API/Base/GDLBatch.vb | 15 +- SCrawler/API/Base/UserDataBase.vb | 40 +- SCrawler/API/Instagram/Declarations.vb | 1 + SCrawler/API/Instagram/SiteSettings.vb | 118 +++- SCrawler/API/Mastodon/UserData.vb | 48 +- SCrawler/API/Pinterest/UserData.vb | 4 +- SCrawler/API/Reddit/UserData.vb | 7 +- SCrawler/API/Twitter/Declarations.vb | 1 - SCrawler/API/Twitter/SiteSettings.vb | 109 ++-- SCrawler/API/Twitter/UserData.vb | 515 +++++++++++------- SCrawler/Download/DownloadProgress.vb | 6 +- .../STDownloader/VideoDownloaderForm.vb | 5 +- .../Editors/GlobalSettingsForm.Designer.vb | 111 ++-- SCrawler/Editors/GlobalSettingsForm.vb | 2 + SCrawler/Editors/UsersInfoForm.vb | 14 +- SCrawler/ListImagesLoader.vb | 2 + SCrawler/MainFrame.Designer.vb | 13 +- SCrawler/MainFrame.vb | 8 +- SCrawler/My Project/AssemblyInfo.vb | 4 +- .../Hosts/DownloadableMediaHost.vb | 14 +- SCrawler/SettingsCLS.vb | 2 + 33 files changed, 938 insertions(+), 635 deletions(-) diff --git a/Changelog.md b/Changelog.md index 30b550d..edb0a79 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,22 @@ +# 2023.6.5.0 + +*2023-06-05* + +- Added + - **Instagram**: add additional authorization headers + - Setting to prevent user icon and banner from downloading (Request #129) + - Add standalone downloader to tray context menu + - YouTube downloader: added `Replace modification date` property + - Minor improvements +- Fixed + - Fascist **Twitter**: posts not downloading (new API) + - Main window: refill bug when the number of filtered profiles = 0 + - Standalone downloader: new items are not added to the queue + - Standalone downloader: bug when not downloaded videos do not appear in the list when loading the program + - Standalone downloader: add videos array not working + - Saved posts: remove main progress perform when downloading saved posts + - Minor bugs + # 2023.5.12.0 *2023-05-12* diff --git a/ProgramScreenshots/SettingsGlobalDownloading.png b/ProgramScreenshots/SettingsGlobalDownloading.png index 8684650e37c54401535703457c0556c08fb7ebe7..3408a10a7f032a0cd3684393861a53d83c20dd17 100644 GIT binary patch literal 19268 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 Zf8xJM=&r2~aI~C(!PC{xWt~$(696bhCFB4A literal 18025 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 F{vTmJGh6@w diff --git a/ProgramScreenshots/SettingsSiteInstagram.png b/ProgramScreenshots/SettingsSiteInstagram.png index 55a02ee7e7a3c40fae5a2bc0ecb97be55379cc67..73cdc922b31faeed4262a17779bc780c58eaebd6 100644 GIT binary patch literal 38269 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%0AVj@!v>g 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 Qf_@?=bxShqhW@kv11v?AYXATM literal 28106 zcmd3Oc|6o>ANEud2_q?yB`HeMLUzI+390P+nteBDEJY;Agh(OTQnrcggQ=9UuW2xb zgselh8I0k*N1gL@p0hm9^M2kx-ak4gnYn-W@?Ed%x_|esXsa{t=GqN`K$tZy!mdIf z+XcX%2?l!bFRIvQE8u_IysxS&LkimtO@bfjZYXIfK_Ep)rgf{G;AcjUi$>lM2umI9 z&o-?4OIrxU)j|WNblu;aNI<;iF$fr^nw^u7xF(^YWtaO6`N{T_-dqdc;sX8IGu?th z@sAItPw?Im7ubyx-v--RXS;XbzLwT);q}lv=2t2jE?L7yVSS$alpgZDmOd}gyRC## z$}1Y_(x`6Gd^Qn9cRF}5`15QJVtJ|uL00G=U+P1Iq}AQ+uDQ89rBHlnI;STn#u!sJ zyK_4P(m}@#GoL@Vc>n@=8z&G6f!wNx!XS_fHVk0N&(F}Yfsb&8GC&{>mx=rfOektu zegILvc*9^W@c`yq@o{%Da{j-tk`w>8O*28mUx z6jCb18g~Vg+()VB{B~mLAdv0?IJB>7KB+ozWT+|6A~2`=+X2i;{O8st_x#n+>YyIc zg+UJW(J-;~{J>F6h?>I2xwP1tP2#y?v9*+SC7=7Id_hVItD$1_zm2w9nuakOTwg42 za^DybU7)zHb5~MgycarlARGPKS2&D()veRur)`?J3*&F>h9Dfs4(hRJNR!`u zz1|oiyY~<~1ai5&Uum>Jk!-LKlO`(|vgBOe#LlXC+%I^g*~>dHK5)Y>Dg*K~2%xkPRId2-rtS>38≥Qt#f4T!_a1G;Cg>K9rC#Riy&pJ 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 diff --git a/ProgramScreenshots/SettingsSiteTwitter.png b/ProgramScreenshots/SettingsSiteTwitter.png index a297c34ee8de5792c9ee03fc51b952740a13ae5c..c24fb2c87bd92e2442c22b4f5140904cd4b1fe33 100644 GIT binary patch literal 17594 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 Lslke5pTGY<(VfB- literal 19424 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 diff --git a/SCrawler.YouTube/Base/YouTubeSettings.vb b/SCrawler.YouTube/Base/YouTubeSettings.vb index 58b604b..4d39da9 100644 --- a/SCrawler.YouTube/Base/YouTubeSettings.vb +++ b/SCrawler.YouTube/Base/YouTubeSettings.vb @@ -94,12 +94,12 @@ Namespace API.YouTube.Base End Property #End Region #Region "Defaults" + + Public ReadOnly Property ReplaceModificationDate As XMLValue(Of Boolean) Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean) - - Public ReadOnly Property ItemsListLimit As XMLValue(Of Integer) Public ReadOnly Property RemoveDownloadedAutomatically As XMLValue(Of Boolean) diff --git a/SCrawler.YouTube/Downloader/MediaItem.vb b/SCrawler.YouTube/Downloader/MediaItem.vb index a7477af..dde218b 100644 --- a/SCrawler.YouTube/Downloader/MediaItem.vb +++ b/SCrawler.YouTube/Downloader/MediaItem.vb @@ -277,6 +277,7 @@ Namespace DownloadObjects.STDownloader #Region "Context buttons' handlers" Public Sub AddToQueue() ControlInvokeFast(Me, Sub() + Pending = True BTT_DOWN.Visible = False SEP_DOWN.Visible = False End Sub, EDP.None) @@ -300,6 +301,8 @@ Namespace DownloadObjects.STDownloader Throw oex Catch ex As Exception ErrorsDescriber.Execute(EDP.SendToLog, ex, $"MediaItem.Download:{vbCr}{MyContainer.ToString}{vbCr}{MyContainer.URL})") + Finally + Pending = False End Try End Sub #End Region diff --git a/SCrawler.YouTube/Downloader/VideoListForm.Designer.vb b/SCrawler.YouTube/Downloader/VideoListForm.Designer.vb index ec1a631..c76cf4a 100644 --- a/SCrawler.YouTube/Downloader/VideoListForm.Designer.vb +++ b/SCrawler.YouTube/Downloader/VideoListForm.Designer.vb @@ -143,7 +143,8 @@ Namespace DownloadObjects.STDownloader Me.BTT_ADD.Size = New System.Drawing.Size(184, 22) Me.BTT_ADD.Tag = "a" Me.BTT_ADD.Text = "Add (Ins)" - Me.BTT_ADD.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." + Me.BTT_ADD.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" & + "dd without downloading." ' 'BTT_ADD_PLS_ARR ' @@ -154,7 +155,8 @@ Namespace DownloadObjects.STDownloader Me.BTT_ADD_PLS_ARR.Size = New System.Drawing.Size(184, 22) Me.BTT_ADD_PLS_ARR.Tag = "pls" Me.BTT_ADD_PLS_ARR.Text = "Add playlist array" - Me.BTT_ADD_PLS_ARR.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." + Me.BTT_ADD_PLS_ARR.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" & + "dd without downloading." ' 'BTT_ADD_NO_SHORTS ' @@ -166,7 +168,7 @@ Namespace DownloadObjects.STDownloader Me.BTT_ADD_NO_SHORTS.Tag = "ans" Me.BTT_ADD_NO_SHORTS.Text = "Add (without Shorts)" Me.BTT_ADD_NO_SHORTS.ToolTipText = "Download all videos except 'Shorts'." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies fo" & - "r download (if supported)." + "r download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to add without downloading." ' 'BTT_ADD_SHORTS_ONLY ' @@ -178,7 +180,7 @@ Namespace DownloadObjects.STDownloader Me.BTT_ADD_SHORTS_ONLY.Tag = "as" Me.BTT_ADD_SHORTS_ONLY.Text = "Add (Shorts only)" Me.BTT_ADD_SHORTS_ONLY.ToolTipText = "Download only 'Shorts' videos." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for down" & - "load (if supported)." + "load (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to add without downloading." ' 'BTT_DOWN ' @@ -187,7 +189,7 @@ Namespace DownloadObjects.STDownloader Me.BTT_DOWN.Name = "BTT_DOWN" Me.BTT_DOWN.Size = New System.Drawing.Size(81, 22) Me.BTT_DOWN.Text = "Download" - Me.BTT_DOWN.ToolTipText = "Download pending items" + Me.BTT_DOWN.ToolTipText = "Download pending items (F5)" ' 'BTT_STOP ' diff --git a/SCrawler.YouTube/Downloader/VideoListForm.resx b/SCrawler.YouTube/Downloader/VideoListForm.resx index 3e09d16..79365c2 100644 --- a/SCrawler.YouTube/Downloader/VideoListForm.resx +++ b/SCrawler.YouTube/Downloader/VideoListForm.resx @@ -134,6 +134,27 @@ + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN1SURBVEhLrZVJTFNRFIafQhgD1OBUpiiKYg22AopFKggK + FdRYQUEZgsqgGBAChaiYRlG2RuPOuCDGGDcG48phgcQog0KFV4QKKZ2wSIJxf83vuc8SWRAw8E7yp23u + yf/de95/X4Wlyu+eT4f/fR8sJL7mbVt+cSOVWcUyB3U4/EUHvUiy6HDKliVBvG3LL26SMKRiQd0CQj8K + CO8XEPnZF5WuXPkAGlHFwnoErOtfhU2D/vQ7FM2efPkASQTgO481+yNxJAwZoxtwe6ZEPoCWALHmAOwZ + USDHGkHz34p7s1XyAc6LGpZsUSDXGomzk9tRZdfg0a86+QCN4j6m/xaFUvsO1DgS0ehMxZNfxv8DLJbz + OZX2p/8uscej1pGMlikdbnqy0fGzCWufBi4q5fPgDmmHWXMZp3znjepw0pqJMlsOap3HcdV9Cnc8ZfQ9 + GdfcB3DLk4O2aT06ZpvweNYogR7O1uHuTAVuTRej2V1AI8xDjb0Qys5gSABuHvqBMt4rIGrQD2qKIU+K + YSIW5+w7ccWZgutTB8lAj/bpXAlw83s2melQ5dDg9EQcssY2Qm0JRfSAHxTkU2gx/APwnXNzvqi2hFCz + Evle83pXClrdmWjz6AmQjRvfM2F0p9GzSEL5pAonxjcjfXQ9EsQQRAz6QtEnIJAuZf6XeYC8ER1iyFxD + O8iyKqUYVjrUaHDtxbWpDLSS6VV3OoyuNNQ796Ca1krtKhwb34QDdFLJfMAX/DJy81WvBRj65gHOWA9B + OxJOMYxCsS0edfQwmygpLWTITRtdqZIaaFTVNBKepqPjMUj7uh47hoOh/OSDEBpxQJcA4RWpkwDv5wEu + iYnMKKYy02gpM41dYCZrNTN9q6LPi8wkXmYPflwi872otKtRNLkNuePRaHGWIb8n43eFuJ+ViFpWREol + aYdIn0m9WiYBeEwXiticeFO72MIqHbtQZIvDETplCp22xlEkrS0qHtOlijeaxAZ2mp5LzlgkkuhGbzEH + otx2UjLxti2//gJqWPZYhPSi42/TcErKWat3xiutv4AKttsShihKyhqKM/9vKJjL+UqLm9SJxSx6wB8K + imHQOwE+byglZhkB5ylh3DyAdr6ax/AlAXpkBBRT/AJp5wJdIOEF6RkBumUEFAwbpJEYekl0gQxdpLdy + ASjL3GhBLZlzQfgD9Y2tq0N6ki0AAAAASUVORK5CYII= + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN5SURBVEhLrZVJTFNRFIafljBIgBqcymAU54oWGSRCK1oU @@ -152,206 +173,185 @@ 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 - epieAAAAAElFTkSuQmCC + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVFSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcQBQgv01tK6 + oSgvUrRgSwUdI2pGxRUUX1CiGI3RRONLsmQftg/bhy0zmXFLdFk2JkjJmMCmCE4wvOmwllL6Cpe9JAv0 + 7H9KqzOWjSf55fae85z/8+9zzr2XQ6M3Pz/KnJDwSduyZcM3JJKPN4nFr2E4wj/5PzGkVKp+k0jaR5Yu + 7bmWmGjAUBQI80/S6DOZ+Lfz878aamggo5cukbv19b4bKlVrlkCwEtORc1mhY4Bh3rZt3/6YPX+eTF+8 + SIbLytwfJifXSKKjYzE9V6R1xYqPBg8eJI9OnSKjJ08SK5ItR46QJpWqXSYQvImUkEVG1OoNELewFy4Q + FmvZxkYyfeIEGdRqPd+IxR8gRQgiOG0ikZWKP6qvJ4+PHSNWJI2fPUv6Ghp8N5TKn6QCQRISnyuCthTY + ysut1DkVn4Y4e/gwmYYxb2UlMcfF9SNNBQSclvj4y8NVVWQUBSzAevQosWHBxJkz5AHa1aJSdabx+clI + 9hcZkssLxsvKrFPnzhEWZqZhisW66QMHyOSePaRJqXTuEImuIrUICDn65ctfb1Io2rt37fI9QdIYGIeb + CeyJCy1zHDpE2lAkk89Pucsw+WMGg23q9Gl/S1g4ZtFetq6OTEHcnJnpTuLxPoewEcgA3XBOJCMSJaNI + p2XHDmLbu5fYa2vJxP79xIliHggN1tb6utTqew9LSqzs8eN+xyzmWOSyNTVPxVN4vMvQqwKpAfFw4A9u + plCY8oNc3nG/osJnr64mDuAymYgbAl4U8+7bR6bgdooK457FvV8c7e1QKDwyPp+KU+erwGLw7KgGgqsU + Cle1pKd32rZuJY6dO4kLeIxG4oXDSRScxAZOlpQQ7/r1xKtWEzfoyMryZggEV7B+N6DOeeAF8WBwV8fG + prbIZJ392dkz7m3biEujIS6GIU6xmDgFAuKMjCTORYvIIJ/va05I8KhiYuiGVoM08DKYVzwY/nbdlsl6 + xyFoh9gEcAAq7CcigvSkp/9lSE7+DvnvAylYkLg/bJWVJptabbHzeC+KAzrWl5g4Y9ZqH6bEx5dgSTRY + mLjXaDzkzM112uF+PvEx8BhYUlNJj07X/86aNRlY+p+vFX+4jMZGx8aNLntU1AviDvSetouKj4Lh8HDS + B37OyPD1lpY+MKhUtE3zF/Hs3n1sorDQHcq5QyQiTwoL/36QlOSj4kMB8W7QAdoZZraX/pP5iuAoNtpz + cz12Pt8v/FxbliwhA0VFv59eu7are/PmcUtKCrkP0TvgFvgRmEHb6tWzvxgM93JlMvqCfPaqd1dVNVDx + iVDicXFkYN26P2oYpgWptYVpae/2Fxc/HEDvg+KtoBk0AbNSOdtVWtr9mVZLN54LwjjuLVusEzExoZ1D + vFoub0aiCdCNFO7PyXmrR68fuSeVPhX/HnwLroNemWzmjl4/iNzlgMux63QDbokkpHMTw9xEUk1APPil + 4h7Iy1P1lJaO3JRKff8W/zosjNyRSmfMGs0Y8vJBLKeromL7uEbjckE06LyvoODPvaHFg8Gty8nJwsYO + 305PJ9cC4uasrNkvNZonRStXfoqcuQKIxc1lZcetxcWeIZXKR53XKRStGJ9PPBhcY3a2nLYD3wyfWa2e + vQrnr/B4FzGnA3MtQoQxCQnR3Xr9F4+Kix1X8vJw+sLrMM4APp2nSfME93p5+Xu/6nRjt7RaZ2FSEv0W + 6IEY0OP6dC39EQMUYFPgutDH/yVAjyY9OZvBGyDkA7cIUMf0Y02v9H4hQU3Q9/+rAWjBgDEO5x9IKtl+ + 4dDtOAAAAABJRU5ErkJggg== iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVBSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC39sVN - xfEiRQu2VNAxomZUXEHxBSWK0RhNNIrJkn3YPmwftsxkxi3RZVEmjJoxgUyROnFBQIe1lL4XLntJFunZ - /5RWZywbT/LL7T3nOf/n3+ecey+HhqW4OM6ckvLp9SVLRq5JJJ+sF4tfw3BMcPJ/YlihUP0mkXSPLl48 - cCk11YChOBAVnKQxaDLxbxYXfz3c0kLGzp0jfc3NgWsqVZdSIFiO6djZrMgxxDBv27dsecSeOUOm29rI - SFWV96P09AZJfHwipmeLdC1b9vH9ffvIw+PHydixY8SGZOvBg6RdpeqWCgRvIiVikVG1+h2IW9mzZwmL - tWxrK5k+epTc12p934rFHyJFCGI410UiGxV/2NxMHh0+TGxImjh1itxuaQlcUyh+yhEI0pD4XBG0pcRe - XW2jzqn4NMTZAwfINIz5a2uJOSnpHtJUQMDpTE4+P1JXR8ZQwApshw4ROxY4T54kFrSrU6Xqzebz05Ec - LDIsk5VMVFXZpk6fJizMTMMUi3XTe/eSyZ07SbtC4d4qEl1EahkQcvRLl77eLpd3927fHniMpHEwATdO - 7IkHLXPt30+uo0g+n59xm2GKxw0G+9SJE8GWsHDMor1sUxOZgrg5P9+bxuN9AWEjkAK64ZxYRiRKR5Fe - 69atxL5rF3E0NhLnnj3EjWI+CN1tbAz0qdV3HlRU2NgjR4KOWcyxyGUbGp6KZ/B456FXB7JC4tEgGNx8 - oTDje5msp7+mJuCorycu4DGZiBcCfhTz795NpuB2igrjnsV9UBzt7ZHLfVI+n4pT55lgIXh2VEPBVQiF - mZ25ub32TZuIa9s24gE+o5H44XASBSexgZMVFcS/di3xq9XEC3qUSn+eQHAB63cA6pwHXhAPB3dFYmJW - p1TaO6hUPvFu3kw8Gg3xMAxxi8XELRAQd2wscS9YQO7y+YGOlBSfKiGBbmg9yAYvgznFwxFs102p1DIB - QQfEnMAFqHCQmBgykJv7lyE9/QryPwA5YF7iwbDX1prsarXVweO9KA7o2GBq6hOzVvsgIzm5AkviwfzE - /UbjfndhodsB93OJj4NHwJqVRQZ0unvvrlyZh6X/+VoJhsdobHWtW+dxxMW9IO5C72m7qPgYGImOJoOg - Oy8vYKms/NWgUtE2zV3Et2PHYWdpqTeSc5dIRB6Xlv5tSUsLUPHhkHg/6AFmhpmx0H8yVxEcxVZHYaHP - wecHhZ9ry6JFZKis7PcTq1f39W/YMGHNyCB3IXoL3AA/0gKUFStmfjYY7hRKpfQF+exV762ra6Hizkji - SUlkaM2aPxoYphOpjaXZ2e/dKy9/MITeh8W7QAdop0UUipm+ysr+z7VauvFcEMXxbtxocyYkRHYO8XqZ - rAOJJkA3UrinoOCtAb1+9E5OzlPxq+A7cBlYMjOf3NLr7yN3KeByHDrdkFciiejcxDA/IKkhJB7+UnH3 - FhWpBiorR6/m5AT+Lf5NVBS5hQJmjWYcecUgkdNXU7NlQqPxeCAadj5YUvLnrsji4eA2FRQosbEjN3Nz - yaWQuFmpnPlKo3lctnz5Z8iZLYBY2FFVdcRWXu4bVKkC1HmTXN6F8bnEw8E1rlolo+24gnVmtXrmIpy/ - wuO1YU4HZluEiGJSUuL79fovH5aXuy4UFeH0RTdhnAF8Ok+T5gju5erq93/R6cZvaLXu0rQ0+i3QAzGg - x/XpWvojAcjB+tB1vo//S4AeTXpyNoA3QMQHbgGgjunHml7p/XyCmqDv/1dD0IIhYxzOP1xr2RYPr44i - AAAAAElFTkSuQmCC + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lFs3 + FceLFC3YgqBjRM2ouILiC0oUozGauPiSLNmH7cP2YctMZtwSXdzGhFE3J5ABAg4XBHRYS+l74bKXZJGe + /U9pdcay8SS/3N5znvN//n3OuffyaAwUFkaZEhI+ur5s2eg1mezDDVLpSxiO8E/+T4yoVOxvMtmNsaVL + +y8nJlZgKAqE+SdpDBmNwp7Cwi9GmpvJ+PnzpLOpyXeNZTtyRaKVmI6cywodwwzzunXr1gfcmTNk5tw5 + MlpZ6X4/ObleFh0di+m5Ih0rVnxwd/9+cv/ECTJ+/DixINl86BBpZdkbcpHoVaSELDKmVr8BcTN39izh + sJZraSEzx46Ru1qt5yup9D2kiEEE77pEYqHi95uayIMjR4gFSZOnT5Pe5mbfNZXqpwyRKAmJTxVBW4qs + VVUW6pyKz0CcO3iQzMCYt6aGmOLi7iCNBSJee3z8hdHaWjKOAmZgOXyYWLHAfuoUuYV2tbNsV7pQmIxk + f5ERhaJosrLSMv3uu4SDmRmY4rBuZt8+MrVrF2lVqZzbJJJLSC0BYp5++fKXW5XKGzd37PA9RNIEmIQb + O/bEhZY5Dhwg11EkWyhMucUwhRMVFdbpkyf9LeHgmEN7ucZGMg1xU3a2O0kg+BTCBiAHdMN5kYxEkowi + XeZt24h1925ia2gg9r17iRPFPBAabGjwdavVg/fKyizc0aN+xxzmOORy9fWPxVMEggvQqwVpAfFw4A9+ + tlic8p1C0dlTXe2z1dURB3AZjcQNAS+KeffsIdNwO02Fcc/h3i+O9nYqlR65UEjFqfNUsBg8OaqB4KvE + 4tT2zMwu6+bNxLF9O3EBj8FAvHA4hYJT2MCpsjLiXbeOeNVq4gadubneLJHoItbvBNS5ADwjHgx+Tmxs + Wrtc3jWUk/PIvWULcWk0xMUwxCmVEqdIRJyRkcS5aBEZFAp9bQkJHjYmhm5oHUgHz4N5xYPhb1ePXD4w + CUEbxOzAAaiwn4gI0p+Z+VdFcvI3yH8HZIAFifvDWlNjtKrVZptA8Kw4oGNDiYmPTFrtvZT4+DIsiQYL + E/caDAec+flOG9zPJz4BHgBzWhrp1+nuvLlqVRaW/udrxR8ug6HFsX69yxYV9Yy4A72n7aLi42A0PJwM + gR+ysnwD5eW/VrAsbdP8RTw7dx6xFxe7Qzl3SCTkYXHx37eSknxUfCQg3gc6gYlhZgfoP5mvCI5iiy0/ + 32MTCv3CT7VlyRIyXFLy+8k1a7r7Nm6cNKekkF8g2gtugh9pAUpOzuzPFRWD+XI5fUE+edW7a2ubqbg9 + lHhcHBleu/aPeoZpR2pDcXr6W3dKS+8No/dB8Q7QBlppEZVqtru8vO8TrZZuPB+E8dybNlnsMTGhnUO8 + TqFoQ6IR0I0U783Le61frx8bzMh4LP4tuAqugIHU1Ee9ev1d5C4HfJ5Npxt2y2QhnRsZ5nsk1QfEg18q + /r6CAra/vHzs64wM37/FvwwLI70oYNJoJpBXCGJ53dXVWyc1GpcLokHnQ0VFf+4OLR4MfmNeXi42drQn + M5NcDoibcnNnP9doHpasXPkxcuYKIBa3VVYetZSWem6zrI86b1QqOzA+n3gw+IbVqxW0HVexzqRWz16C + 8xcEgnOY04G5FiHCmISE6D69/rP7paWOiwUFOH3hjRhngJDO06R5gn+lqurt2zrdxE2t1lmclES/BXog + BfS4Pl5Lf8QAJdgQuC708X8O0KNJT85G8AoI+cAtAtQx/VjTK71fSFAT9P3/YgBaMGCMx/sHyjLY+hqD + P/QAAAAASUVORK5CYII= iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVBSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC39sVN - xfEiRQu2VNAxomZUXEHxBSWK0RhNNIrJkn3YPmwftsxkxi3RZVEmjJoxgUyROnFBQIe1lL4XLntJFunZ - /5RWZywbT/LL7T3nOf/n3+ecey+HhqW4OM6ckvLp9SVLRq5JJJ+sF4tfw3BMcPJ/YlihUP0mkXSPLl48 - cCk11YChOBAVnKQxaDLxbxYXfz3c0kLGzp0jfc3NgWsqVZdSIFiO6djZrMgxxDBv27dsecSeOUOm29rI - SFWV96P09AZJfHwipmeLdC1b9vH9ffvIw+PHydixY8SGZOvBg6RdpeqWCgRvIiVikVG1+h2IW9mzZwmL - tWxrK5k+epTc12p934rFHyJFCGI410UiGxV/2NxMHh0+TGxImjh1itxuaQlcUyh+yhEI0pD4XBG0pcRe - XW2jzqn4NMTZAwfINIz5a2uJOSnpHtJUQMDpTE4+P1JXR8ZQwApshw4ROxY4T54kFrSrU6Xqzebz05Ec - LDIsk5VMVFXZpk6fJizMTMMUi3XTe/eSyZ07SbtC4d4qEl1EahkQcvRLl77eLpd3927fHniMpHEwATdO - 7IkHLXPt30+uo0g+n59xm2GKxw0G+9SJE8GWsHDMor1sUxOZgrg5P9+bxuN9AWEjkAK64ZxYRiRKR5Fe - 69atxL5rF3E0NhLnnj3EjWI+CN1tbAz0qdV3HlRU2NgjR4KOWcyxyGUbGp6KZ/B456FXB7JC4tEgGNx8 - oTDje5msp7+mJuCorycu4DGZiBcCfhTz795NpuB2igrjnsV9UBzt7ZHLfVI+n4pT55lgIXh2VEPBVQiF - mZ25ub32TZuIa9s24gE+o5H44XASBSexgZMVFcS/di3xq9XEC3qUSn+eQHAB63cA6pwHXhAPB3dFYmJW - p1TaO6hUPvFu3kw8Gg3xMAxxi8XELRAQd2wscS9YQO7y+YGOlBSfKiGBbmg9yAYvgznFwxFs102p1DIB - QQfEnMAFqHCQmBgykJv7lyE9/QryPwA5YF7iwbDX1prsarXVweO9KA7o2GBq6hOzVvsgIzm5AkviwfzE - /UbjfndhodsB93OJj4NHwJqVRQZ0unvvrlyZh6X/+VoJhsdobHWtW+dxxMW9IO5C72m7qPgYGImOJoOg - Oy8vYKms/NWgUtE2zV3Et2PHYWdpqTeSc5dIRB6Xlv5tSUsLUPHhkHg/6AFmhpmx0H8yVxEcxVZHYaHP - wecHhZ9ry6JFZKis7PcTq1f39W/YMGHNyCB3IXoL3AA/0gKUFStmfjYY7hRKpfQF+exV762ra6Hizkji - SUlkaM2aPxoYphOpjaXZ2e/dKy9/MITeh8W7QAdop0UUipm+ysr+z7VauvFcEMXxbtxocyYkRHYO8XqZ - rAOJJkA3UrinoOCtAb1+9E5OzlPxq+A7cBlYMjOf3NLr7yN3KeByHDrdkFciiejcxDA/IKkhJB7+UnH3 - FhWpBiorR6/m5AT+Lf5NVBS5hQJmjWYcecUgkdNXU7NlQqPxeCAadj5YUvLnrsji4eA2FRQosbEjN3Nz - yaWQuFmpnPlKo3lctnz5Z8iZLYBY2FFVdcRWXu4bVKkC1HmTXN6F8bnEw8E1rlolo+24gnVmtXrmIpy/ - wuO1YU4HZluEiGJSUuL79fovH5aXuy4UFeH0RTdhnAF8Ok+T5gju5erq93/R6cZvaLXu0rQ0+i3QAzGg - x/XpWvojAcjB+tB1vo//S4AeTXpyNoA3QMQHbgGgjunHml7p/XyCmqDv/1dD0IIhYxzOP1xr2RYPr44i - AAAAAElFTkSuQmCC + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lFs3 + FceLFC3YgqBjRM2ouILiC0oUozGauPiSLNmH7cP2YctMZtwSXdzGhFE3J5ABAg4XBHRYS+l74bKXZJGe + /U9pdcay8SS/3N5znvN//n3OuffyaAwUFkaZEhI+ur5s2eg1mezDDVLpSxiO8E/+T4yoVOxvMtmNsaVL + +y8nJlZgKAqE+SdpDBmNwp7Cwi9GmpvJ+PnzpLOpyXeNZTtyRaKVmI6cywodwwzzunXr1gfcmTNk5tw5 + MlpZ6X4/ObleFh0di+m5Ih0rVnxwd/9+cv/ECTJ+/DixINl86BBpZdkbcpHoVaSELDKmVr8BcTN39izh + sJZraSEzx46Ru1qt5yup9D2kiEEE77pEYqHi95uayIMjR4gFSZOnT5Pe5mbfNZXqpwyRKAmJTxVBW4qs + VVUW6pyKz0CcO3iQzMCYt6aGmOLi7iCNBSJee3z8hdHaWjKOAmZgOXyYWLHAfuoUuYV2tbNsV7pQmIxk + f5ERhaJosrLSMv3uu4SDmRmY4rBuZt8+MrVrF2lVqZzbJJJLSC0BYp5++fKXW5XKGzd37PA9RNIEmIQb + O/bEhZY5Dhwg11EkWyhMucUwhRMVFdbpkyf9LeHgmEN7ucZGMg1xU3a2O0kg+BTCBiAHdMN5kYxEkowi + XeZt24h1925ia2gg9r17iRPFPBAabGjwdavVg/fKyizc0aN+xxzmOORy9fWPxVMEggvQqwVpAfFw4A9+ + tlic8p1C0dlTXe2z1dURB3AZjcQNAS+KeffsIdNwO02Fcc/h3i+O9nYqlR65UEjFqfNUsBg8OaqB4KvE + 4tT2zMwu6+bNxLF9O3EBj8FAvHA4hYJT2MCpsjLiXbeOeNVq4gadubneLJHoItbvBNS5ADwjHgx+Tmxs + Wrtc3jWUk/PIvWULcWk0xMUwxCmVEqdIRJyRkcS5aBEZFAp9bQkJHjYmhm5oHUgHz4N5xYPhb1ePXD4w + CUEbxOzAAaiwn4gI0p+Z+VdFcvI3yH8HZIAFifvDWlNjtKrVZptA8Kw4oGNDiYmPTFrtvZT4+DIsiQYL + E/caDAec+flOG9zPJz4BHgBzWhrp1+nuvLlqVRaW/udrxR8ug6HFsX69yxYV9Yy4A72n7aLi42A0PJwM + gR+ysnwD5eW/VrAsbdP8RTw7dx6xFxe7Qzl3SCTkYXHx37eSknxUfCQg3gc6gYlhZgfoP5mvCI5iiy0/ + 32MTCv3CT7VlyRIyXFLy+8k1a7r7Nm6cNKekkF8g2gtugh9pAUpOzuzPFRWD+XI5fUE+edW7a2ubqbg9 + lHhcHBleu/aPeoZpR2pDcXr6W3dKS+8No/dB8Q7QBlppEZVqtru8vO8TrZZuPB+E8dybNlnsMTGhnUO8 + TqFoQ6IR0I0U783Le61frx8bzMh4LP4tuAqugIHU1Ee9ev1d5C4HfJ5Npxt2y2QhnRsZ5nsk1QfEg18q + /r6CAra/vHzs64wM37/FvwwLI70oYNJoJpBXCGJ53dXVWyc1GpcLokHnQ0VFf+4OLR4MfmNeXi42drQn + M5NcDoibcnNnP9doHpasXPkxcuYKIBa3VVYetZSWem6zrI86b1QqOzA+n3gw+IbVqxW0HVexzqRWz16C + 8xcEgnOY04G5FiHCmISE6D69/rP7paWOiwUFOH3hjRhngJDO06R5gn+lqurt2zrdxE2t1lmclES/BXog + BfS4Pl5Lf8QAJdgQuC708X8O0KNJT85G8AoI+cAtAtQx/VjTK71fSFAT9P3/YgBaMGCMx/sHyjLY+hqD + P/QAAAAASUVORK5CYII= iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVBSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC39sVN - xfEiRQu2VNAxomZUXEHxBSWK0RhNNIrJkn3YPmwftsxkxi3RZVEmjJoxgUyROnFBQIe1lL4XLntJFunZ - /5RWZywbT/LL7T3nOf/n3+ecey+HhqW4OM6ckvLp9SVLRq5JJJ+sF4tfw3BMcPJ/YlihUP0mkXSPLl48 - cCk11YChOBAVnKQxaDLxbxYXfz3c0kLGzp0jfc3NgWsqVZdSIFiO6djZrMgxxDBv27dsecSeOUOm29rI - SFWV96P09AZJfHwipmeLdC1b9vH9ffvIw+PHydixY8SGZOvBg6RdpeqWCgRvIiVikVG1+h2IW9mzZwmL - tWxrK5k+epTc12p934rFHyJFCGI410UiGxV/2NxMHh0+TGxImjh1itxuaQlcUyh+yhEI0pD4XBG0pcRe - XW2jzqn4NMTZAwfINIz5a2uJOSnpHtJUQMDpTE4+P1JXR8ZQwApshw4ROxY4T54kFrSrU6Xqzebz05Ec - LDIsk5VMVFXZpk6fJizMTMMUi3XTe/eSyZ07SbtC4d4qEl1EahkQcvRLl77eLpd3927fHniMpHEwATdO - 7IkHLXPt30+uo0g+n59xm2GKxw0G+9SJE8GWsHDMor1sUxOZgrg5P9+bxuN9AWEjkAK64ZxYRiRKR5Fe - 69atxL5rF3E0NhLnnj3EjWI+CN1tbAz0qdV3HlRU2NgjR4KOWcyxyGUbGp6KZ/B456FXB7JC4tEgGNx8 - oTDje5msp7+mJuCorycu4DGZiBcCfhTz795NpuB2igrjnsV9UBzt7ZHLfVI+n4pT55lgIXh2VEPBVQiF - mZ25ub32TZuIa9s24gE+o5H44XASBSexgZMVFcS/di3xq9XEC3qUSn+eQHAB63cA6pwHXhAPB3dFYmJW - p1TaO6hUPvFu3kw8Gg3xMAxxi8XELRAQd2wscS9YQO7y+YGOlBSfKiGBbmg9yAYvgznFwxFs102p1DIB - QQfEnMAFqHCQmBgykJv7lyE9/QryPwA5YF7iwbDX1prsarXVweO9KA7o2GBq6hOzVvsgIzm5AkviwfzE - /UbjfndhodsB93OJj4NHwJqVRQZ0unvvrlyZh6X/+VoJhsdobHWtW+dxxMW9IO5C72m7qPgYGImOJoOg - Oy8vYKms/NWgUtE2zV3Et2PHYWdpqTeSc5dIRB6Xlv5tSUsLUPHhkHg/6AFmhpmx0H8yVxEcxVZHYaHP - wecHhZ9ry6JFZKis7PcTq1f39W/YMGHNyCB3IXoL3AA/0gKUFStmfjYY7hRKpfQF+exV762ra6Hizkji - SUlkaM2aPxoYphOpjaXZ2e/dKy9/MITeh8W7QAdop0UUipm+ysr+z7VauvFcEMXxbtxocyYkRHYO8XqZ - rAOJJkA3UrinoOCtAb1+9E5OzlPxq+A7cBlYMjOf3NLr7yN3KeByHDrdkFciiejcxDA/IKkhJB7+UnH3 - FhWpBiorR6/m5AT+Lf5NVBS5hQJmjWYcecUgkdNXU7NlQqPxeCAadj5YUvLnrsji4eA2FRQosbEjN3Nz - yaWQuFmpnPlKo3lctnz5Z8iZLYBY2FFVdcRWXu4bVKkC1HmTXN6F8bnEw8E1rlolo+24gnVmtXrmIpy/ - wuO1YU4HZluEiGJSUuL79fovH5aXuy4UFeH0RTdhnAF8Ok+T5gju5erq93/R6cZvaLXu0rQ0+i3QAzGg - x/XpWvojAcjB+tB1vo//S4AeTXpyNoA3QMQHbgGgjunHml7p/XyCmqDv/1dD0IIhYxzOP1xr2RYPr44i - AAAAAElFTkSuQmCC + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lFs3 + FceLFC3YgqBjRM2ouILiC0oUozGauPiSLNmH7cP2YctMZtwSXdzGhFE3J5ABAg4XBHRYS+l74bKXZJGe + /U9pdcay8SS/3N5znvN//n3OuffyaAwUFkaZEhI+ur5s2eg1mezDDVLpSxiO8E/+T4yoVOxvMtmNsaVL + +y8nJlZgKAqE+SdpDBmNwp7Cwi9GmpvJ+PnzpLOpyXeNZTtyRaKVmI6cywodwwzzunXr1gfcmTNk5tw5 + MlpZ6X4/ObleFh0di+m5Ih0rVnxwd/9+cv/ECTJ+/DixINl86BBpZdkbcpHoVaSELDKmVr8BcTN39izh + sJZraSEzx46Ru1qt5yup9D2kiEEE77pEYqHi95uayIMjR4gFSZOnT5Pe5mbfNZXqpwyRKAmJTxVBW4qs + VVUW6pyKz0CcO3iQzMCYt6aGmOLi7iCNBSJee3z8hdHaWjKOAmZgOXyYWLHAfuoUuYV2tbNsV7pQmIxk + f5ERhaJosrLSMv3uu4SDmRmY4rBuZt8+MrVrF2lVqZzbJJJLSC0BYp5++fKXW5XKGzd37PA9RNIEmIQb + O/bEhZY5Dhwg11EkWyhMucUwhRMVFdbpkyf9LeHgmEN7ucZGMg1xU3a2O0kg+BTCBiAHdMN5kYxEkowi + XeZt24h1925ia2gg9r17iRPFPBAabGjwdavVg/fKyizc0aN+xxzmOORy9fWPxVMEggvQqwVpAfFw4A9+ + tlic8p1C0dlTXe2z1dURB3AZjcQNAS+KeffsIdNwO02Fcc/h3i+O9nYqlR65UEjFqfNUsBg8OaqB4KvE + 4tT2zMwu6+bNxLF9O3EBj8FAvHA4hYJT2MCpsjLiXbeOeNVq4gadubneLJHoItbvBNS5ADwjHgx+Tmxs + Wrtc3jWUk/PIvWULcWk0xMUwxCmVEqdIRJyRkcS5aBEZFAp9bQkJHjYmhm5oHUgHz4N5xYPhb1ePXD4w + CUEbxOzAAaiwn4gI0p+Z+VdFcvI3yH8HZIAFifvDWlNjtKrVZptA8Kw4oGNDiYmPTFrtvZT4+DIsiQYL + E/caDAec+flOG9zPJz4BHgBzWhrp1+nuvLlqVRaW/udrxR8ug6HFsX69yxYV9Yy4A72n7aLi42A0PJwM + gR+ysnwD5eW/VrAsbdP8RTw7dx6xFxe7Qzl3SCTkYXHx37eSknxUfCQg3gc6gYlhZgfoP5mvCI5iiy0/ + 32MTCv3CT7VlyRIyXFLy+8k1a7r7Nm6cNKekkF8g2gtugh9pAUpOzuzPFRWD+XI5fUE+edW7a2ubqbg9 + lHhcHBleu/aPeoZpR2pDcXr6W3dKS+8No/dB8Q7QBlppEZVqtru8vO8TrZZuPB+E8dybNlnsMTGhnUO8 + TqFoQ6IR0I0U783Le61frx8bzMh4LP4tuAqugIHU1Ee9ev1d5C4HfJ5Npxt2y2QhnRsZ5nsk1QfEg18q + /r6CAra/vHzs64wM37/FvwwLI70oYNJoJpBXCGJ53dXVWyc1GpcLokHnQ0VFf+4OLR4MfmNeXi42drQn + M5NcDoibcnNnP9doHpasXPkxcuYKIBa3VVYetZSWem6zrI86b1QqOzA+n3gw+IbVqxW0HVexzqRWz16C + 8xcEgnOY04G5FiHCmISE6D69/rP7paWOiwUFOH3hjRhngJDO06R5gn+lqurt2zrdxE2t1lmclES/BXog + BfS4Pl5Lf8QAJdgQuC708X8O0KNJT85G8AoI+cAtAtQx/VjTK71fSFAT9P3/YgBaMGCMx/sHyjLY+hqD + P/QAAAAASUVORK5CYII= diff --git a/SCrawler.YouTube/Downloader/VideoListForm.vb b/SCrawler.YouTube/Downloader/VideoListForm.vb index 94503a1..7548a32 100644 --- a/SCrawler.YouTube/Downloader/VideoListForm.vb +++ b/SCrawler.YouTube/Downloader/VideoListForm.vb @@ -81,7 +81,13 @@ Namespace DownloadObjects.STDownloader If Not MyYouTubeSettings Is Nothing Then MyYouTubeSettings.Close() End Sub Private Sub VideoListForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown - If e.KeyCode = Keys.Insert Then BTT_ADD.PerformClick() : e.Handled = True + Dim b As Boolean = True + Select Case e.KeyCode + Case Keys.Insert : BTT_ADD.PerformClick() + Case Keys.F5 : BTT_DOWN.PerformClick() + Case Else : b = False + End Select + If b Then e.Handled = True End Sub #End Region #Region "Refill, save list" @@ -230,83 +236,74 @@ Namespace DownloadObjects.STDownloader BTT_ADD_NO_SHORTS.KeyClick, BTT_ADD_SHORTS_ONLY.KeyClick Dim pForm As ParsingProgressForm = Nothing Try - Dim canProcess As Boolean = True - If TP_CONTROLS.Controls.Count >= MyYouTubeSettings.ItemsListLimit Then canProcess = TP_CONTROLS.Controls.Cast(Of MediaItem).ListExists(ControlsDownloaded) - If canProcess Then - Dim useCookies As Boolean = MyYouTubeSettings.DefaultUseCookies - If e.Control Then useCookies = True - Dim useCookiesParse As Boolean? = Nothing - If useCookies Then useCookiesParse = True + Dim useCookies As Boolean = MyYouTubeSettings.DefaultUseCookies + Dim disableDown As Boolean = e.Shift + If e.Control Then useCookies = True + Dim useCookiesParse As Boolean? = Nothing + If useCookies Then useCookiesParse = True - Dim c As IYouTubeMediaContainer = Nothing - Dim url$ = String.Empty - Dim GetDefault As Boolean = True - Dim GetShorts As Boolean = True + Dim c As IYouTubeMediaContainer = Nothing + Dim url$ = String.Empty + Dim GetDefault As Boolean = True + Dim GetShorts As Boolean = True - If Sender.Tag = "pls" Then - Using pf As New PlaylistArrayForm With {.DesignXML = DesignXML} - pf.ShowDialog() - If pf.DialogResult = DialogResult.OK Then - With pf.URLs - If .Count > 0 Then - pForm = New ParsingProgressForm - pForm.Show() - pForm.SetInitialValues(.Count, "Parsing playlists...") - Dim containers As New List(Of IYouTubeMediaContainer) - For Each u$ In .Self : containers.Add(YouTubeFunctions.Parse(u, useCookiesParse, pForm.Token, pForm.MyProgress, True, False)) : pForm.MyProgress.Perform() : Next - pForm.Dispose() - If containers.Count > 0 Then containers.ListDisposeRemoveAll(Function(cc) cc.HasError Or Not cc.Exists) - If containers.Count > 0 Then - c = New Channel With {.UserTitle = IIf(pf.IsOneArtist, containers(0).UserTitle, "Playlists")} - c.Elements.AddRange(containers) - End If + If Sender.Tag = "pls" Then + Using pf As New PlaylistArrayForm With {.DesignXML = DesignXML} + pf.ShowDialog() + If pf.DialogResult = DialogResult.OK Then + With pf.URLs + If .Count > 0 Then + pForm = New ParsingProgressForm + pForm.Show() + pForm.SetInitialValues(.Count, "Parsing playlists...") + Dim containers As New List(Of IYouTubeMediaContainer) + For Each u$ In .Self : containers.Add(YouTubeFunctions.Parse(u, useCookiesParse, pForm.Token, pForm.MyProgress, True, False)) : pForm.MyProgress.Perform() : Next + pForm.Dispose() + If containers.Count > 0 Then containers.ListDisposeRemoveAll(Function(cc) cc.HasError Or Not cc.Exists) + If containers.Count > 0 Then + c = New Channel With {.UserTitle = IIf(pf.IsOneArtist, containers(0).UserTitle, "Playlists")} + c.Elements.AddRange(containers) End If - End With - End If - End Using - Else - Select Case CStr(Sender.Tag) - Case "ans" : GetShorts = False - Case "as" : GetDefault = False : GetShorts = True - End Select - url = BufferText - If url.IsEmptyString OrElse Not YouTubeFunctions.IsMyUrl(url) Then url = InputBoxE("Enter a valid URL to the YouTube video:", "YouTube link") - End If - - If Not c Is Nothing OrElse YouTubeFunctions.IsMyUrl(url) Then - If c Is Nothing Then - pForm = New ParsingProgressForm - pForm.Show() - pForm.SetInitialValues(1, "Parsing data...") - c = YouTubeFunctions.Parse(url, useCookiesParse, pForm.Token, pForm.MyProgress, GetDefault, GetShorts) - pForm.Dispose() - End If - If Not c Is Nothing Then - Dim f As Form - Select Case c.ObjectType - Case YouTubeMediaType.Single : f = New VideoOptionsForm(c) - Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList - If c.IsMusic Then - f = New MusicPlaylistsForm(c) - Else - f = New VideoOptionsForm(c) - End If - Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType") - End Select - If Not f Is Nothing Then - If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML - f.ShowDialog() - If f.DialogResult = DialogResult.OK Then - If TP_CONTROLS.Controls.Count >= MyYouTubeSettings.ItemsListLimit Then _ - RemoveControls(TP_CONTROLS.Controls.Cast(Of MediaItem).LastOrDefault(ControlsDownloaded)) - ControlCreateAndAdd(c) End If - f.Dispose() - End If + End With + End If + End Using + Else + Select Case CStr(Sender.Tag) + Case "ans" : GetShorts = False + Case "as" : GetDefault = False : GetShorts = True + End Select + url = BufferText + If url.IsEmptyString OrElse Not YouTubeFunctions.IsMyUrl(url) Then url = InputBoxE("Enter a valid URL to the YouTube video:", "YouTube link") + End If + + If Not c Is Nothing OrElse YouTubeFunctions.IsMyUrl(url) Then + If c Is Nothing Then + pForm = New ParsingProgressForm + pForm.Show() + pForm.SetInitialValues(1, "Parsing data...") + c = YouTubeFunctions.Parse(url, useCookiesParse, pForm.Token, pForm.MyProgress, GetDefault, GetShorts) + pForm.Dispose() + End If + If Not c Is Nothing Then + Dim f As Form + Select Case c.ObjectType + Case YouTubeMediaType.Single : f = New VideoOptionsForm(c) + Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList + If c.IsMusic Then + f = New MusicPlaylistsForm(c) + Else + f = New VideoOptionsForm(c) + End If + Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType") + End Select + If Not f Is Nothing Then + If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML + f.ShowDialog() + If f.DialogResult = DialogResult.OK Then ControlCreateAndAdd(c, disableDown) + f.Dispose() End If End If - Else - MsgBoxE({$"Number of items to download exceeded!{vbCr}Reduce the number of items or increase the limit.", "New download"}, vbCritical) End If Catch oex As OperationCanceledException Catch dex As ObjectDisposedException @@ -425,8 +422,10 @@ Namespace DownloadObjects.STDownloader UpdateLogButton() End Sub Protected Sub AddToDownload(ByRef Item As MediaItem, ByVal RunThread As Boolean) - If MyJob.Count = 0 OrElse Not MyJob.Items.Exists(Function(i) i.MyContainer.GetHashCode) Then - Item.Pending = True + Dim hc% = Item.MyContainer.GetHashCode + If MyJob.Count = 0 OrElse Not MyJob.Items.Exists(Function(i) i.MyContainer.GetHashCode = hc) Then + 'TODELETE: YT video downloader 'Item.Pending' + 'Item.Pending = True MyJob.Add(Item) Item.AddToQueue() If RunThread Then StartDownloading() @@ -475,7 +474,10 @@ Namespace DownloadObjects.STDownloader Task.WaitAll(t.ToArray) MyProgress.Perform(t.Count) If Indexes.Count > 0 Then - For i = Indexes.Count - 1 To 0 Step -1 : MyJob.Items.RemoveAt(Indexes(i)) : Next + For i = Indexes.Count - 1 To 0 Step -1 + MyJob.Item(Indexes(i)).Pending = False + MyJob.Items.RemoveAt(Indexes(i)) + Next End If t.Clear() End If diff --git a/SCrawler.YouTube/My Project/AssemblyInfo.vb b/SCrawler.YouTube/My Project/AssemblyInfo.vb index d48214c..06b0f20 100644 --- a/SCrawler.YouTube/My Project/AssemblyInfo.vb +++ b/SCrawler.YouTube/My Project/AssemblyInfo.vb @@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices ' by using the '*' as shown below: ' - - + + diff --git a/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb b/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb index 8460109..f980353 100644 --- a/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb +++ b/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb @@ -440,7 +440,7 @@ Namespace API.YouTube.Objects End Get End Property Protected _Exists As Boolean = True - Public ReadOnly Property Exists As Boolean Implements IDownloadableMedia.Exists + Public Overridable ReadOnly Property Exists As Boolean Implements IDownloadableMedia.Exists Get If Not _Exists Then Return False @@ -643,6 +643,7 @@ Namespace API.YouTube.Objects End If If Not cmd.IsEmptyString Then cmd = $"yt-dlp -f ""{cmd}""" + If Not MyYouTubeSettings.ReplaceModificationDate Then cmd &= " --no-mtime" cmd.StringAppend(formats, " ") cmd.StringAppend(subs, " ") cmd.StringAppend(YouTubeFunctions.GetCookiesCommand(WithCookies, YouTubeCookieNetscapeFile), " ") @@ -864,6 +865,7 @@ Namespace API.YouTube.Objects .Information = $"Download {MediaType}" End With End If + .MainProcessName = "yt-dlp" .FileExchanger = MyCache.NewInstance(Of BatchFileExchanger)(CachePath, EDP.ReturnValue) .FileExchanger.DeleteCacheOnDispose = True .AddCommand("chcp 65001") diff --git a/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb b/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb index e83e5cd..e0932f9 100644 --- a/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb +++ b/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb @@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices ' by using the '*' as shown below: ' - - + + diff --git a/SCrawler/API/Base/GDLBatch.vb b/SCrawler/API/Base/GDLBatch.vb index 7715b3c..4899285 100644 --- a/SCrawler/API/Base/GDLBatch.vb +++ b/SCrawler/API/Base/GDLBatch.vb @@ -72,15 +72,22 @@ Namespace API.Base.GDL Friend Const UrlTextStart As String = UrlLibStart & " https" Friend Sub New() MyBase.New(True) + MainProcessName = "gallery-dl" ChangeDirectory(Settings.GalleryDLFile.File) End Sub + Public Overrides Sub Create() + If TempPostsList Is Nothing Then TempPostsList = New List(Of String) + MyBase.Create() + End Sub Protected Overrides Async Sub OutputDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs) - MyBase.OutputDataReceiver(Sender, e) - Await Validate(e.Data) + If Not ProcessKilled Then + MyBase.OutputDataReceiver(Sender, e) + Await Validate(e.Data) + End If End Sub Protected Overridable Async Function Validate(ByVal Value As String) As Task - If Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso - TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill(EDP.None) + If Not ProcessKilled AndAlso Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso + TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill() End Function End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Base/UserDataBase.vb b/SCrawler/API/Base/UserDataBase.vb index a37d02e..5dc1973 100644 --- a/SCrawler/API/Base/UserDataBase.vb +++ b/SCrawler/API/Base/UserDataBase.vb @@ -126,6 +126,7 @@ Namespace API.Base Private Const Name_ReadyForDownload As String = "ReadyForDownload" Private Const Name_DownloadImages As String = "DownloadImages" Private Const Name_DownloadVideos As String = "DownloadVideos" + Private Const Name_IconBannerDownloaded As String = "IconBannerDownloaded" Private Const Name_VideoCount As String = "VideoCount" Private Const Name_PicturesCount As String = "PicturesCount" @@ -434,6 +435,18 @@ BlockNullPicture: Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages Friend Property DownloadVideos As Boolean = True Implements IUserData.DownloadVideos Friend Property DownloadMissingOnly As Boolean = False Implements IUserData.DownloadMissingOnly + Private _IconBannerDownloaded As Boolean = False + Friend WriteOnly Property IconBannerDownloaded As Boolean + Set(ByVal IsDownloaded As Boolean) + If Not _IconBannerDownloaded = IsDownloaded Then _ForceSaveUserInfo = True + _IconBannerDownloaded = IsDownloaded + End Set + End Property + Friend ReadOnly Property DownloadIconBanner As Boolean + Get + Return Not _IconBannerDownloaded Or Settings.UpdateUserIconBannerEveryTime + End Get + End Property #End Region #Region "Content" Protected ReadOnly _ContentList As List(Of UserMedia) @@ -751,6 +764,7 @@ BlockNullPicture: ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True) DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True) DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True) + _IconBannerDownloaded = x.Value(Name_IconBannerDownloaded).FromXML(Of Boolean)(False) DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0) DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0) LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing) @@ -799,6 +813,7 @@ BlockNullPicture: x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger) x.Add(Name_DownloadImages, DownloadImages.BoolToInteger) x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger) + x.Add(Name_IconBannerDownloaded, _IconBannerDownloaded.BoolToInteger) x.Add(Name_VideoCount, DownloadedVideos(True)) x.Add(Name_PicturesCount, DownloadedPictures(True)) x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty)) @@ -934,12 +949,12 @@ BlockNullPicture: _EnvirUserExists = UserExists _EnvirUserSuspended = UserSuspended _EnvirChanged = False + _EnvirInvokeUserUpdated = False UserExists = True UserSuspended = False DownloadedPictures(False) = 0 DownloadedVideos(False) = 0 _PictureExists = Settings.ViewModeIsPicture AndAlso Not GetPicture(Of Image)(False) Is Nothing - _EnvirInvokeUserUpdated = False End Sub Private Sub EnvirChanged(ByVal NewValue As Object, Optional ByVal Caller As String = Nothing) If _DownloadInProgress Then @@ -997,8 +1012,10 @@ BlockNullPicture: If UseMD5Comparison Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token) - If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then _ - TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None) + If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then + If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd) + TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None) + End If _ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd) DownloadContent(Token) ThrowIfDisposed() @@ -1079,7 +1096,8 @@ BlockNullPicture: Progress = Data.Progress If Not Responser Is Nothing Then Responser.Dispose() Responser = New Responser - If Not HOST Is Nothing AndAlso Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser) + If Not HOST Is Nothing AndAlso HOST.Available(ISiteSettings.Download.SingleObject, True) AndAlso + Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser) SeparateVideoFolder = False IsSingleObjectDownload = True DownloadSingleObject_GetPosts(Data, Token) @@ -1338,6 +1356,16 @@ BlockNullPicture: Dim f As SFile Dim v As UserMedia Dim fileNumProvider As SFileNumbers = SFileNumbers.Default + Dim __deleteFile As Action(Of SFile, String) = Sub(ByVal FileToDelete As SFile, ByVal FileUrl As String) + Try + If FileToDelete.Exists Then FileToDelete.Delete(,, EDP.ThrowException) + Catch file_io_ex As IOException + MyMainLOG = "File download aborted. You should download the following file again." & vbCr & + $"File: {FileToDelete}{vbCr}URL: {FileUrl}" + Catch file_del_ex As Exception + ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex) + End Try + End Sub Using w As New OptionalWebClient(Me) If vsf Then CSFileP($"{MyDir}\Video\").Exists(SFO.Path) @@ -1426,7 +1454,9 @@ BlockNullPicture: DownloadContentDefault_PostProcessing(v, f, Token) dCount += 1 Catch woex As OperationCanceledException When Token.IsCancellationRequested - If f.Exists Then f.Delete() + 'TODELETE: UserDataBase.DownloadContentDefault: remove file when 'OperationCanceledException' + 'If f.Exists Then f.Delete(,, EDP.SendToLog) + __deleteFile.Invoke(f, v.URL_BASE) v.State = UStates.Missing v.Attempts += 1 _ContentNew(i) = v diff --git a/SCrawler/API/Instagram/Declarations.vb b/SCrawler/API/Instagram/Declarations.vb index 93b46d5..e8bed4c 100644 --- a/SCrawler/API/Instagram/Declarations.vb +++ b/SCrawler/API/Instagram/Declarations.vb @@ -46,6 +46,7 @@ Namespace API.Instagram If Not token.IsEmptyString Then Destination.Headers.Add(SiteSettings.Header_CSRF_TOKEN, token) If Not isInternal Then Destination.Cookies.Update(Source.Cookies, CookieKeeper.UpdateModes.ReplaceByNameAll, False, EDP.SendToLog) + Destination.Cookies.Update(EDP.SendToLog) Destination.SaveSettings() End If End If diff --git a/SCrawler/API/Instagram/SiteSettings.vb b/SCrawler/API/Instagram/SiteSettings.vb index 78a8df7..0536199 100644 --- a/SCrawler/API/Instagram/SiteSettings.vb +++ b/SCrawler/API/Instagram/SiteSettings.vb @@ -70,33 +70,54 @@ Namespace API.Instagram End Class #End Region #Region "Authorization properties" - - Friend ReadOnly Property HashTagged As PropertyValue - - Friend ReadOnly Property CSRF_TOKEN As PropertyValue - - Friend Property IG_APP_ID As PropertyValue - - Friend Property IG_WWW_CLAIM As PropertyValue - Friend Overrides Function BaseAuthExists() As Boolean - Return Responser.CookiesExists And ACheck(IG_APP_ID.Value) And ACheck(CSRF_TOKEN.Value) - End Function Private Const Header_IG_APP_ID As String = "x-ig-app-id" Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim" Friend Const Header_CSRF_TOKEN As String = "x-csrftoken" + Private Const Header_ASBD_ID As String = "X-Asbd-Id" + Private ReadOnly Header_Browser As New HttpHeader("Sec-Ch-Ua", """Google Chrome"";v=""113"", ""Chromium"";v=""113"", ""Not-A.Brand"";v=""24""") + Private ReadOnly Header_BrowserExt As New HttpHeader("Sec-Ch-Ua-Full-Version-List", """Google Chrome"";v=""113.0.5672.127"", ""Chromium"";v=""113.0.5672.127"", ""Not-A.Brand"";v=""24.0.0.0""") + Private ReadOnly Header_Platform As New HttpHeader("Sec-Ch-Ua-Platform-Version", """10.0.0""") + + Friend ReadOnly Property HashTagged As PropertyValue + + Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue + + Friend Property HH_IG_APP_ID As PropertyValue + + Friend Property HH_ASBD_ID As PropertyValue + + Friend Property HH_IG_WWW_CLAIM As PropertyValue + + Private Property HH_BROWSER As PropertyValue + + Private Property HH_BROWSER_EXT As PropertyValue + + Private Property HH_PLATFORM As PropertyValue + + Private Property HH_USER_AGENT As PropertyValue + Friend Overrides Function BaseAuthExists() As Boolean + Return Responser.CookiesExists And ACheck(HH_IG_APP_ID.Value) And ACheck(HH_CSRF_TOKEN.Value) + End Function Private _FieldsChangerSuspended As Boolean = False Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object) If Not _FieldsChangerSuspended And Not PropName.IsEmptyString Then Dim f$ = String.Empty + Dim isUserAgent As Boolean = False Select Case PropName - Case NameOf(IG_APP_ID) : f = Header_IG_APP_ID - Case NameOf(IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM - Case NameOf(CSRF_TOKEN) : f = Header_CSRF_TOKEN + Case NameOf(HH_IG_APP_ID) : f = Header_IG_APP_ID + Case NameOf(HH_ASBD_ID) : f = Header_ASBD_ID + Case NameOf(HH_IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM + Case NameOf(HH_CSRF_TOKEN) : f = Header_CSRF_TOKEN + Case NameOf(HH_BROWSER) : f = Header_Browser.Name + Case NameOf(HH_BROWSER_EXT) : f = Header_BrowserExt.Name + Case NameOf(HH_PLATFORM) : f = Header_Platform.Name + Case NameOf(HH_USER_AGENT) : isUserAgent = True End Select If Not f.IsEmptyString Then Responser.Headers.Remove(f) If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value)) - Responser.SaveSettings() + ElseIf isUserAgent Then + Responser.UserAgent = CStr(Value) End If End If End Sub @@ -192,13 +213,53 @@ Namespace API.Instagram Dim app_id$ = String.Empty Dim www_claim$ = String.Empty Dim token$ = String.Empty + Dim asbd$ = String.Empty + Dim browser$ = String.Empty + Dim browserExt$ = String.Empty + Dim platform$ = String.Empty + Dim useragent$ = String.Empty + + Dim __UpdateHeader As Action(Of HttpHeader, Boolean) = Sub(ByVal h As HttpHeader, ByVal UpdateValueIfEmpty As Boolean) + With Responser.Headers + Dim i% = .IndexOf(h) + Dim hh As HttpHeader + If i >= 0 Then + hh = .Item(i) + If hh.Value.IsEmptyString And UpdateValueIfEmpty Then hh.Value = h.Value + Else + hh = h + End If + .Add(hh) + End With + End Sub With Responser - If .Headers.Count > 0 Then - token = .Headers.Value(Header_CSRF_TOKEN) - app_id = .Headers.Value(Header_IG_APP_ID) - www_claim = .Headers.Value(Header_IG_WWW_CLAIM) - End If + .Accept = "*/*" + useragent = .UserAgent + With .Headers + If .Count > 0 Then + token = .Value(Header_CSRF_TOKEN) + app_id = .Value(Header_IG_APP_ID) + www_claim = .Value(Header_IG_WWW_CLAIM) + asbd = .Value(Header_ASBD_ID) + browser = .Value(Header_Browser.Name) + browserExt = .Value(Header_BrowserExt.Name) + platform = .Value(Header_Platform.Name) + End If + .Add("Dnt", 1) + __UpdateHeader(Header_Browser, browser.IsEmptyString) + browser = .Value(Header_Browser.Name) + __UpdateHeader(Header_BrowserExt, browserExt.IsEmptyString) + browserExt = .Value(Header_BrowserExt.Name) + .Add("Sec-Ch-Ua-Mobile", "?0") + .Add("Sec-Ch-Ua-Platform", """Windows""") + __UpdateHeader(Header_Platform, platform.IsEmptyString) + platform = .Value(Header_Platform.Name) + .Add("Sec-Fetch-Dest", "empty") + .Add("Sec-Fetch-Mode", "cors") + .Add("Sec-Fetch-Site", "same-origin") + .Add("X-Requested-With", "XMLHttpRequest") + End With .CookiesExtractMode = Responser.CookiesExtractModes.Response .CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll .CookiesExtractedAutoSave = False @@ -207,9 +268,14 @@ Namespace API.Instagram Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString} HashTagged = New PropertyValue(String.Empty, GetType(String)) - CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(CSRF_TOKEN), v)) - IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_APP_ID), v)) - IG_WWW_CLAIM = New PropertyValue(www_claim.IfNullOrEmpty(0), GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v)) + HH_CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_CSRF_TOKEN), v)) + HH_IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_APP_ID), v)) + HH_ASBD_ID = New PropertyValue(asbd, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_ASBD_ID), v)) + HH_IG_WWW_CLAIM = New PropertyValue(www_claim.IfNullOrEmpty(0), GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_WWW_CLAIM), v)) + HH_BROWSER = New PropertyValue(browser, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_BROWSER), v)) + HH_BROWSER_EXT = New PropertyValue(browserExt, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_BROWSER_EXT), v)) + HH_PLATFORM = New PropertyValue(platform, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_PLATFORM), v)) + HH_USER_AGENT = New PropertyValue(useragent, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_USER_AGENT), v)) DownloadTimeline = New PropertyValue(True) DownloadStories = New PropertyValue(True) @@ -275,7 +341,7 @@ Namespace API.Instagram Private _NextTagged As Boolean = True Friend Overrides Sub DownloadStarted(ByVal What As Download) ActiveJobs += 1 - If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(IG_WWW_CLAIM.Value) Then IG_WWW_CLAIM.Value = "0" + If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(HH_IG_WWW_CLAIM.Value) Then HH_IG_WWW_CLAIM.Value = "0" End Sub Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download) With DirectCast(User, UserData) @@ -299,8 +365,8 @@ Namespace API.Instagram LastDownloadDate.Value = Now LastRequestsCount.Value = .RequestsCount _FieldsChangerSuspended = True - IG_WWW_CLAIM.Value = Responser.Headers.Value(Header_IG_WWW_CLAIM) - CSRF_TOKEN.Value = Responser.Headers.Value(Header_CSRF_TOKEN) + HH_IG_WWW_CLAIM.Value = Responser.Headers.Value(Header_IG_WWW_CLAIM) + HH_CSRF_TOKEN.Value = Responser.Headers.Value(Header_CSRF_TOKEN) _FieldsChangerSuspended = False End With End Sub diff --git a/SCrawler/API/Mastodon/UserData.vb b/SCrawler/API/Mastodon/UserData.vb index d8f4487..e39da20 100644 --- a/SCrawler/API/Mastodon/UserData.vb +++ b/SCrawler/API/Mastodon/UserData.vb @@ -13,6 +13,7 @@ Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Tools.Web.Documents.JSON Imports UTypes = SCrawler.API.Base.UserMedia.Types +Imports UStates = SCrawler.API.Base.UserMedia.States Namespace API.Mastodon Friend Class UserData : Inherits Twitter.UserData #Region "XML names" @@ -136,11 +137,14 @@ Namespace API.Mastodon If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg" __imgFile.Path = MyFile.CutPath.Path If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None) + If __imgFile.Exists Then IconBannerDownloaded = True End If End If End Sub - __getImage.Invoke(.Value("header").IfNullOrEmpty(.Value("header_static"))) - __getImage.Invoke(.Value("avatar").IfNullOrEmpty(.Value("avatar_static"))) + If DownloadIconBanner Then + __getImage.Invoke(.Value("header").IfNullOrEmpty(.Value("header_static"))) + __getImage.Invoke(.Value("avatar").IfNullOrEmpty(.Value("avatar_static"))) + End If End If End With End If @@ -235,8 +239,44 @@ Namespace API.Mastodon Return $"https://{Domain}/api/v1/statuses/" & "{0}" End Function Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken) - SinglePostUrl = GetSinglePostPattern(MyCredentials.Domain) - MyBase.ReparseMissing(Token) + Dim rList As New List(Of Integer) + Dim URL$ = String.Empty + Try + If ContentMissingExists Then + Dim SinglePostUrl$ = GetSinglePostPattern(MyCredentials.Domain) + Dim m As UserMedia + Dim r$, PostDate$ + Dim j As EContainer + ProgressPre.ChangeMax(_ContentList.Count) + For i% = 0 To _ContentList.Count - 1 + ProgressPre.Perform() + If _ContentList(i).State = UStates.Missing Then + m = _ContentList(i) + If Not m.Post.ID.IsEmptyString Then + ThrowAny(Token) + URL = String.Format(SinglePostUrl, m.Post.ID) + r = Responser.GetResponse(URL,, EDP.ReturnValue) + If Not r.IsEmptyString Then + j = JsonDocument.Parse(r) + If Not j Is Nothing Then + PostDate = String.Empty + If j.Contains("created_at") Then PostDate = j("created_at").Value Else PostDate = String.Empty + ObtainMedia(j, m.Post.ID, PostDate, UStates.Missing) + rList.Add(i) + End If + End If + End If + End If + Next + End If + Catch ex As Exception + ProcessException(ex, Token, $"ReparseMissing error [{URL}]") + Finally + If rList.Count > 0 Then + For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(i) : Next + rList.Clear() + End If + End Try End Sub #End Region #Region "DownloadSingleObject" diff --git a/SCrawler/API/Pinterest/UserData.vb b/SCrawler/API/Pinterest/UserData.vb index a829522..5843e3a 100644 --- a/SCrawler/API/Pinterest/UserData.vb +++ b/SCrawler/API/Pinterest/UserData.vb @@ -270,11 +270,11 @@ Namespace API.Pinterest If IsBoardsRequested Then If ErrorOutputData.Count > 0 Then If Await Task.Run(Of Boolean)(Function() ErrorOutputData.Exists(Function(ee) Not ee.IsEmptyString AndAlso - ee.StartsWith(UrlTextStart))) Then Kill(EDP.None) + ee.StartsWith(UrlTextStart))) Then Kill() End If Else If Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso - Source._TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill(EDP.None) + Source._TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill() End If End Function End Class diff --git a/SCrawler/API/Reddit/UserData.vb b/SCrawler/API/Reddit/UserData.vb index e02837e..37d8c64 100644 --- a/SCrawler/API/Reddit/UserData.vb +++ b/SCrawler/API/Reddit/UserData.vb @@ -427,11 +427,14 @@ Namespace API.Reddit If f.Extension.IsEmptyString Then f.Extension = "jpg" f.Path = dir.Path If Not f.Exists Then GetWebFile(img, f, EDP.ReturnValue) + If f.Exists Then IconBannerDownloaded = True End If End If End Sub - __getFile.Invoke(.Value("icon_img")) - __getFile.Invoke(.Value("banner_img")) + If DownloadIconBanner Then + __getFile.Invoke(.Value("icon_img")) + __getFile.Invoke(.Value("banner_img")) + End If End With End If End Using diff --git a/SCrawler/API/Twitter/Declarations.vb b/SCrawler/API/Twitter/Declarations.vb index cee4a04..ac2a3fa 100644 --- a/SCrawler/API/Twitter/Declarations.vb +++ b/SCrawler/API/Twitter/Declarations.vb @@ -14,7 +14,6 @@ Namespace API.Twitter Friend Const TwitterSite As String = "Twitter" Friend Const TwitterSiteKey As String = "AndyProgram_Twitter" Friend ReadOnly DateProvider As ADateTime = GetDateProvider() - Friend ReadOnly VideoNode As NodeParams() = {New NodeParams("video_info", True, True, True, True, 10)} Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue) Private Function GetDateProvider() As ADateTime Dim n As DateTimeFormatInfo = CultureInfo.GetCultureInfo("en-us").DateTimeFormat.Clone diff --git a/SCrawler/API/Twitter/SiteSettings.vb b/SCrawler/API/Twitter/SiteSettings.vb index 358f89b..f1b1cf7 100644 --- a/SCrawler/API/Twitter/SiteSettings.vb +++ b/SCrawler/API/Twitter/SiteSettings.vb @@ -12,7 +12,7 @@ Imports SCrawler.Plugin.Attributes Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Tools.Web.Clients Namespace API.Twitter - + Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Token names" Friend Const Header_Authorization As String = "authorization" @@ -41,19 +41,20 @@ Namespace API.Twitter Return My.Resources.SiteResources.TwitterPic_400 End Get End Property -#Region "Auth" - - Private ReadOnly Property Auth As PropertyValue - - Private ReadOnly Property Token As PropertyValue -#End Region + 'TODELETE: twitter headers + '#Region "Auth" + ' + ' Private ReadOnly Property Auth As PropertyValue + ' + ' Private ReadOnly Property Token As PropertyValue + '#End Region #Region "Other properties" - + Friend ReadOnly Property GifsDownload As PropertyValue - + Friend ReadOnly Property GifsSpecialFolder As PropertyValue - + Friend ReadOnly Property GifsPrefix As PropertyValue Private ReadOnly Property GifStringChecker As IFormatProvider @@ -75,68 +76,52 @@ Namespace API.Twitter Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]") End Function End Class - + Friend ReadOnly Property UseMD5Comparison As PropertyValue + + Friend ReadOnly Property ConcurrentDownloads As PropertyValue #End Region - Friend Overrides ReadOnly Property Responser As Responser - Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object) - If Not PropName.IsEmptyString Then - Dim f$ = String.Empty - Select Case PropName - Case NameOf(Auth) : f = Header_Authorization - Case NameOf(Token) : f = Header_Token - End Select - If Not f.IsEmptyString Then - Responser.Headers.Remove(f) - If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value)) - Responser.SaveSettings() - End If - End If - End Sub + 'TODELETE: twitter headers + 'Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object) + ' If Not PropName.IsEmptyString Then + ' Dim f$ = String.Empty + ' Select Case PropName + ' Case NameOf(Auth) : f = Header_Authorization + ' Case NameOf(Token) : f = Header_Token + ' End Select + ' If Not f.IsEmptyString Then + ' Responser.Headers.Remove(f) + ' If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value)) + ' Responser.SaveSettings() + ' End If + ' End If + 'End Sub #End Region Friend Sub New() - MyBase.New(TwitterSite) - Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml") With {.DeclaredError = EDP.ThrowException} + MyBase.New(TwitterSite, "twitter.com") - Dim a$ = String.Empty - Dim t$ = String.Empty + 'TODELETE: twitter headers + 'Dim a$ = String.Empty + 'Dim t$ = String.Empty With Responser - If .File.Exists Then - .CookiesDomain = "twitter.com" - .CookiesEncryptKey = SettingsCLS.CookieEncryptKey - .LoadSettings() - a = .Headers.Value(Header_Authorization) - t = .Headers.Value(Header_Token) - Else - .ContentType = "application/json" - .Accept = "*/*" - .CookiesDomain = "twitter.com" - .CookiesEncryptKey = SettingsCLS.CookieEncryptKey - .Decoders.Add(SymbolsConverter.Converters.Unicode) - .Headers.Add("sec-ch-ua", """Chromium"";v=""112"", ""Google Chrome"";v=""112"", ""Not:A-Brand"";v=""99""") - .Headers.Add("sec-ch-ua-mobile", "?0") - .Headers.Add("sec-fetch-dest", "empty") - .Headers.Add("sec-fetch-mode", "cors") - .Headers.Add("sec-fetch-site", "same-origin") - .Headers.Add(Header_Token, String.Empty) - .Headers.Add("x-twitter-active-user", "yes") - .Headers.Add("x-twitter-auth-type", "OAuth2Session") - .Headers.Add(Header_Authorization, String.Empty) - .SaveSettings() - End If + 'TODELETE: twitter headers + 'a = .Headers.Value(Header_Authorization) + 't = .Headers.Value(Header_Token) .Cookies.ChangedAllowInternalDrop = False .Cookies.Changed = False End With - Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v)) - Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v)) + 'TODELETE: twitter headers + 'Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v)) + 'Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v)) GifsDownload = New PropertyValue(True) GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String)) GifsPrefix = New PropertyValue("GIF_") GifStringChecker = New GifStringProvider UseMD5Comparison = New PropertyValue(False) + ConcurrentDownloads = New PropertyValue(1) UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1) UrlPatternUser = "https://twitter.com/{0}" @@ -151,18 +136,10 @@ Namespace API.Twitter Return $"https://twitter.com/{User.Name}/status/{Media.Post.ID}" End Function Friend Overrides Function BaseAuthExists() As Boolean - Return Responser.CookiesExists And ACheck(Token.Value) And ACheck(Auth.Value) + Return Responser.CookiesExists End Function Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean - If MyBase.Available(What, Silent) Then - If What = ISiteSettings.Download.SavedPosts Then - Return Settings.GalleryDLFile.Exists - Else - Return True - End If - Else - Return False - End If + Return Settings.GalleryDLFile.Exists And BaseAuthExists() End Function Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) If Options Is Nothing OrElse (Not TypeOf Options Is EditorExchangeOptions OrElse diff --git a/SCrawler/API/Twitter/UserData.vb b/SCrawler/API/Twitter/UserData.vb index 4b62129..ac546b8 100644 --- a/SCrawler/API/Twitter/UserData.vb +++ b/SCrawler/API/Twitter/UserData.vb @@ -6,19 +6,17 @@ ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY -Imports System.Net Imports System.Threading Imports SCrawler.API.Base Imports SCrawler.API.YouTube.Objects Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.RegularExpressions -Imports PersonalUtilities.Tools.Web.Clients +Imports PersonalUtilities.Tools Imports PersonalUtilities.Tools.Web.Documents.JSON Imports UStates = SCrawler.API.Base.UserMedia.States Imports UTypes = SCrawler.API.Base.UserMedia.Types Namespace API.Twitter Friend Class UserData : Inherits UserDataBase - Protected SinglePostUrl As String = "https://api.twitter.com/1.1/statuses/show.json?id={0}&tweet_mode=extended" #Region "XML names" Private Const Name_GifsDownload As String = "GifsDownload" Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder" @@ -29,6 +27,19 @@ Namespace API.Twitter Friend Property GifsSpecialFolder As String = String.Empty Friend Property GifsPrefix As String = String.Empty Private ReadOnly _DataNames As List(Of String) + Private ReadOnly Property MySettings As SiteSettings + Get + Return HOST.Source + End Get + End Property + Private FileNameProvider As ANumbers = Nothing + Private Sub ResetFileNameProvider(Optional ByVal GroupSize As Integer? = Nothing) + FileNameProvider = New ANumbers With {.FormatOptions = ANumbers.Options.FormatNumberGroup + ANumbers.Options.Groups} + FileNameProvider.GroupSize = If(GroupSize, 3) + End Sub + Private Function RenameGdlFile(ByVal Input As SFile, ByVal i As Integer) As SFile + Return SFile.Rename(Input, $"{Input.PathWithSeparator}{i.NumToString(FileNameProvider)}.{Input.Extension}",, EDP.ThrowException) + End Function #End Region #Region "Exchange options" Friend Overrides Function ExchangeOptionsGet() As Object @@ -79,134 +90,157 @@ Namespace API.Twitter DownloadData_SavedPosts(Token) Else If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly) - DownloadData(String.Empty, Token) + DownloadData_Timeline(Token) End If End Sub - Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken) + Private Sub DownloadData_Timeline(ByVal Token As CancellationToken) Dim URL$ = String.Empty + Dim tCache As CacheKeeper = Nothing Try Dim PostID$ = String.Empty - Dim PostDate$ + Dim PostDate$, tmpUserId$ + Dim j As EContainer Dim nn As EContainer Dim NewPostDetected As Boolean = False Dim ExistsDetected As Boolean = False - Dim UID As Func(Of EContainer, String) = Function(e) e.XmlIfNothing.Item({"user", "id"}).XmlIfNothingValue - - URL = $"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={Name}&count=200&exclude_replies=false&include_rts=1&tweet_mode=extended" - If Not POST.IsEmptyString Then URL &= $"&max_id={POST}" - - ThrowAny(Token) - Dim r$ = Responser.GetResponse(URL) - If Not r.IsEmptyString Then - Using w As EContainer = JsonDocument.Parse(r) - If w.ListExists Then - - If POST.IsEmptyString And Not w.ItemF({0, "user"}) Is Nothing Then - With w.ItemF({0, "user"}) - If .Value("screen_name").StringToLower = Name.ToLower Then - UserSiteNameUpdate(.Value("name")) - UserDescriptionUpdate(.Value("description")) - Dim __getImage As Action(Of String) = Sub(ByVal img As String) - If Not img.IsEmptyString Then - Dim __imgFile As SFile = UrlFile(img, True) - If Not __imgFile.Name.IsEmptyString Then - If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg" - __imgFile.Path = MyFile.CutPath.Path - If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None) - End If - End If - End Sub - Dim icon$ = .Value("profile_image_url_https") - If Not icon.IsEmptyString Then icon = icon.Replace("_normal", String.Empty) - __getImage.Invoke(.Value("profile_banner_url")) - __getImage.Invoke(icon) + tCache = New CacheKeeper($"{DownloadContentDefault_GetRootDir()}\_tCache\") + If tCache.RootDirectory.Exists(SFO.Path, False) Then tCache.RootDirectory.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.ReturnValue) + tCache.Validate() + Dim f As SFile = GetTimelineFromGalleryDL(tCache.RootDirectory, Token) + If Not f.IsEmptyString Then + ThrowAny(Token) + Dim timelineFiles As List(Of SFile) = SFile.GetFiles(f, "*.txt",, EDP.ReturnValue) + If timelineFiles.ListExists Then + Dim i% + ResetFileNameProvider(Math.Max(timelineFiles.Count.ToString.Length, 2)) + 'rename files + For i = 0 To timelineFiles.Count - 1 : timelineFiles(i) = RenameGdlFile(timelineFiles(i), i) : Next + 'parse files + For i = 0 To timelineFiles.Count - 1 + j = JsonDocument.Parse(timelineFiles(i).GetText) + If Not j Is Nothing Then + If i = 0 Then + Dim resValue$ = j.Value({"data", "user", "result"}, "__typename").StringTrim.StringToLower + If resValue.IsEmptyString Then + UserExists = False + j.Dispose() + Exit Sub + ElseIf resValue = "userunavailable" Then + UserSuspended = True + j.Dispose() + Exit Sub + Else + With j({"data", "user", "result"}) + If .ListExists Then + If ID.IsEmptyString Then + ID = .Value("rest_id") + If Not ID.IsEmptyString Then _ForceSaveUserInfo = True + End If + With .Item({"legacy"}) + If .ListExists Then + If .Value("screen_name").StringToLower = Name.ToLower Then + UserSiteNameUpdate(.Value("name")) + UserDescriptionUpdate(.Value("description")) + Dim __getImage As Action(Of String) = Sub(ByVal img As String) + If Not img.IsEmptyString Then + Dim __imgFile As SFile = UrlFile(img, True) + If Not __imgFile.Name.IsEmptyString Then + If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg" + __imgFile.Path = MyFile.CutPath.Path + If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None) + If __imgFile.Exists Then IconBannerDownloaded = True + End If + End If + End Sub + Dim icon$ = .Value("profile_image_url_https") + If Not icon.IsEmptyString Then icon = icon.Replace("_normal", String.Empty) + If DownloadIconBanner Then + __getImage.Invoke(.Value("profile_banner_url")) + __getImage.Invoke(icon) + End If + End If + End If + End With + End If + End With End If - End With + Else + With j({"globalObjects", "tweets"}) + If .ListExists Then + ProgressPre.ChangeMax(.Count) + For Each nn In .Self + ProgressPre.Perform() + If nn.Count > 0 Then + PostID = nn.Value("id") + + 'Date Pattern: + 'Sat Jan 01 01:10:15 +0000 2000 + If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty + Select Case CheckDatesLimit(PostDate, Declarations.DateProvider) + Case DateResult.Skip : Continue For + Case DateResult.Exit : Exit Sub + End Select + + If Not _TempPostsList.Contains(PostID) Then + NewPostDetected = True + _TempPostsList.Add(PostID) + Else + ExistsDetected = True + Continue For + End If + + tmpUserId = nn.ItemF({"extended_entities", "media", 0, "source_user_id"}). + XmlIfNothingValue.IfNullOrEmpty(nn.Value("user_id")).IfNullOrEmpty("/") + + If Not ParseUserMediaOnly OrElse (Not ID.IsEmptyString AndAlso tmpUserId = ID) Then _ + ObtainMedia(nn, PostID, PostDate) + End If + Next + End If + End With + End If + j.Dispose() End If - - With If(IsSavedPosts, w({"globalObjects", "tweets"}).XmlIfNothing, w) - ProgressPre.ChangeMax(.Count) - For Each nn In .Self - ProgressPre.Perform() - ThrowAny(Token) - If nn.Count > 0 Then - PostID = nn.Value("id") - If ID.IsEmptyString Then - ID = UID(nn) - If Not ID.IsEmptyString Then UpdateUserInformation() - End If - - 'Date Pattern: - 'Sat Jan 01 01:10:15 +0000 2000 - If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty - Select Case CheckDatesLimit(PostDate, Declarations.DateProvider) - Case DateResult.Skip : Continue For - Case DateResult.Exit : Exit Sub - End Select - - If Not _TempPostsList.Contains(PostID) Then - NewPostDetected = True - _TempPostsList.Add(PostID) - Else - ExistsDetected = True - Continue For - End If - - If Not ParseUserMediaOnly OrElse - (Not nn.Contains("retweeted_status") OrElse (Not ID.IsEmptyString AndAlso UID(nn("retweeted_status")) = ID)) Then _ - ObtainMedia(nn, PostID, PostDate) - End If - Next - End With - End If - End Using - - If POST.IsEmptyString And ExistsDetected Then Exit Sub - If Not PostID.IsEmptyString And NewPostDetected Then DownloadData(PostID, Token) + Next + End If End If Catch ex As Exception ProcessException(ex, Token, $"data downloading error [{URL}]") + Finally + If Not tCache Is Nothing Then tCache.Dispose() End Try End Sub Private Sub DownloadData_SavedPosts(ByVal Token As CancellationToken) Try - Dim urls As List(Of String) = GetBookmarksUrlsFromGalleryDL() - If urls.ListExists Then - Dim postIds As New List(Of String) - Dim r$ + Dim f As SFile = GetDataFromGalleryDL("https://twitter.com/i/bookmarks", Settings.Cache, True, Token) + Dim files As List(Of SFile) = SFile.GetFiles(f, "*.txt") + If files.ListExists Then + ResetFileNameProvider(Math.Max(files.Count.ToString.Length, 3)) + Dim id$ Dim j As EContainer, jj As EContainer Dim jErr As New ErrorsDescriber(EDP.ReturnValue) - Dim rPattern As RParams = RParams.DM("(?<=tweet-)(\d+)\Z", 0, EDP.ReturnValue) - ProgressPre.ChangeMax(urls.Count) - For Each url$ In urls - ProgressPre.Perform() - r = Responser.GetResponse(url) - If Not r.IsEmptyString Then - j = JsonDocument.Parse(r, jErr) - If Not j Is Nothing Then - jj = j.ItemF({"data", "bookmark_timeline_v2", "timeline", "instructions", 0, "entries"}) - If If(jj?.Count, 0) > 0 Then postIds.ListAddList(jj.Select(Function(jj2) CStr(RegexReplace(jj2.Value("entryId"), rPattern))), LNC) - j.Dispose() - End If + For i% = 0 To files.Count - 1 + f = RenameGdlFile(files(i), i) + j = JsonDocument.Parse(f.GetText, jErr) + If Not j Is Nothing Then + With j.ItemF({"data", 0, "timeline", "instructions", 0, "entries"}) + If .ListExists Then + ProgressPre.ChangeMax(.Count) + For Each jj In .Self + ProgressPre.Perform() + With jj({"content", "itemContent", "tweet_results", "result", "legacy"}) + If .ListExists Then + id = .Value("id_str") + If _TempPostsList.Contains(id) Then j.Dispose() : Exit Sub Else ObtainMedia(.Self, id, .Value("created_at")) + End If + End With + Next + End If + End With + j.Dispose() End If Next - If postIds.Count > 0 Then postIds.RemoveAll(Function(pid) pid.IsEmptyString OrElse (_TempPostsList.Contains(pid) Or _DataNames.Contains(pid))) - If postIds.Count > 0 Then - ProgressPre.ChangeMax(postIds.Count) - For Each __id$ In postIds - ProgressPre.Perform() - _TempPostsList.Add(__id) - r = Responser.GetResponse(String.Format(SinglePostUrl, __id),, EDP.ReturnValue) - If Not r.IsEmptyString Then - j = JsonDocument.Parse(r, jErr) - If Not j Is Nothing Then - If j.Count > 0 Then ObtainMedia(j, __id, j.Value("created_at")) - j.Dispose() - End If - End If - Next - End If End If Catch ex As Exception ProcessException(ex, Token, "data downloading error (Saved Posts)") @@ -215,21 +249,22 @@ Namespace API.Twitter #End Region #Region "Obtain media" Private Sub ObtainMedia(ByVal e As EContainer, ByVal PostID As String, ByVal PostDate As String, Optional ByVal State As UStates = UStates.Unknown) - If Not CheckVideoNode(e, PostID, PostDate, State) Then - Dim s As EContainer = e.ItemF({"extended_entities", "media"}) - If s Is Nothing OrElse s.Count = 0 Then s = e.ItemF({"retweeted_status", "extended_entities", "media"}) - If If(s?.Count, 0) > 0 Then - For Each m In s - If m.Contains("media_url") Then - Dim dName$ = UrlFile(m("media_url").Value) + Dim s As EContainer = e.ItemF({"extended_entities", "media"}) + If s Is Nothing OrElse s.Count = 0 Then s = e.ItemF({"retweeted_status", "extended_entities", "media"}) + If If(s?.Count, 0) > 0 Then + Dim mUrl$ + For Each m As EContainer In s + If Not CheckVideoNode(m, PostID, PostDate, State) Then + mUrl = m.Value("media_url").IfNullOrEmpty(m.Value("media_url_https")) + If Not mUrl.IsEmptyString Then + Dim dName$ = UrlFile(mUrl) If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then _DataNames.Add(dName) - _TempMediaList.ListAddValue(MediaFromData(m("media_url").Value, - PostID, PostDate, GetPictureOption(m), State, UTypes.Picture), LNC) + _TempMediaList.ListAddValue(MediaFromData(mUrl, PostID, PostDate, GetPictureOption(m), State, UTypes.Picture), LNC) End If End If - Next - End If + End If + Next End If End Sub Private Function CheckVideoNode(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String, @@ -260,34 +295,32 @@ Namespace API.Twitter Dim url$, ff$ Dim f As SFile Dim m As UserMedia - With w({"extended_entities", "media"}) - If .ListExists Then - For Each n As EContainer In .Self - If n.Value("type") = "animated_gif" Then - With n({"video_info", "variants"}) - If .ListExists Then - With .ItemF({gifUrl}) - If .ListExists Then - url = .Value("url") - ff = UrlFile(url) - If Not ff.IsEmptyString Then - If GifsDownload And Not _DataNames.Contains(ff) Then - m = MediaFromData(url, PostID, PostDate,, State, UTypes.Video) - f = m.File - If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f - If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*" - _TempMediaList.ListAddValue(m, LNC) - End If - Return True + If w.ListExists Then + For Each n As EContainer In w + If n.Value("type") = "animated_gif" Then + With n({"video_info", "variants"}) + If .ListExists Then + With .ItemF({gifUrl}) + If .ListExists Then + url = .Value("url") + ff = UrlFile(url) + If Not ff.IsEmptyString Then + If GifsDownload And Not _DataNames.Contains(ff) Then + m = MediaFromData(url, PostID, PostDate,, State, UTypes.Video) + f = m.File + If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f + If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*" + _TempMediaList.ListAddValue(m, LNC) End If + Return True End If - End With - End If - End With - End If - Next - End If - End With + End If + End With + End If + End With + End If + Next + End If Return False Catch ex As Exception LogError(ex, "[API.Twitter.UserData.CheckForGif]") @@ -295,64 +328,153 @@ Namespace API.Twitter End Try End Function Private Function GetVideoNodeURL(ByVal w As EContainer) As String - Dim v As EContainer = w.GetNode(VideoNode) - If v.ListExists Then - Dim l As New List(Of Sizes) - Dim u$ - Dim nn As EContainer - For Each n As EContainer In v - If n.Count > 0 Then - For Each nn In n - If nn("content_type").XmlIfNothingValue("none").Contains("mp4") AndAlso nn.Contains("url") Then - u = nn.Value("url") + With w({"video_info", "variants"}) + If .ListExists Then + Dim l As New List(Of Sizes) + Dim u$ + For Each n As EContainer In .Self + If n.Count > 0 Then + If n("content_type").XmlIfNothingValue("none").Contains("mp4") AndAlso n.Contains("url") Then + u = n.Value("url") l.Add(New Sizes(RegexReplace(u, VideoSizeRegEx), u)) End If - Next - End If - Next - If l.Count > 0 Then l.RemoveAll(Function(s) s.HasError) - If l.Count > 0 Then l.Sort() : Return l(0).Data - End If + End If + Next + If l.Count > 0 Then l.RemoveAll(Function(s) s.HasError) + If l.Count > 0 Then l.Sort() : Return l(0).Data + End If + End With Return String.Empty End Function #End Region #Region "Gallery-DL Support" - Private Function GetBookmarksUrlsFromGalleryDL() As List(Of String) - Dim command$ = $"gallery-dl --verbose --simulate --cookies ""{DirectCast(HOST.Source, SiteSettings).CookiesNetscapeFile}"" https://twitter.com/i/bookmarks" + Private Class TwitterGDL : Inherits GDL.GDLBatch + Private Property Token As CancellationToken + Friend Sub New(ByVal Dir As SFile, ByVal _Token As CancellationToken) + MyBase.New + Commands.Clear() + ChangeDirectory(Dir) + Token = _Token + End Sub + Protected Overrides Async Function Validate(ByVal Value As String) As Task + If Not ProcessKilled AndAlso Await Task.Run(Function() Token.IsCancellationRequested OrElse IdExists(Value)) Then Kill() + End Function + Private Function IdExists(ByVal Value As String) As Boolean + Try + Value = Value.StringTrim + If Not Value.IsEmptyString AndAlso (Value.StartsWith("*") Or Value.StartsWith(".\gallery-dl\")) Then + Dim id$ = Value.Split("\").Last.Split(".").First.Split("_").First + If Not id.IsEmptyString Then Return TempPostsList.Contains(id) + End If + Catch ex As Exception + End Try + Return False + End Function + End Class + Private Function GetDataFromGalleryDL(ByVal URL As String, ByVal Cache As CacheKeeper, ByVal UseTempPostList As Boolean, + Optional ByVal Token As CancellationToken = Nothing) As SFile + Dim command$ = $"""{Settings.GalleryDLFile}"" --verbose --no-download --no-skip --cookies ""{MySettings.CookiesNetscapeFile}"" --write-pages " Try - Using batch As New GDL.GDLBatch With {.TempPostsList = _TempPostsList} : Return GDL.GetUrlsFromGalleryDl(batch, command) : End Using - Catch ex As Exception - HasError = True - LogError(ex, $"GetJson({command})") + Dim dir As SFile = Cache.NewPath + If dir.Exists(SFO.Path,, EDP.ThrowException) Then + Using batch As New TwitterGDL(dir, Token) + If UseTempPostList Then + batch.TempPostsList = _TempPostsList + command &= GdlGetIdFilterString() + End If + command &= URL + '#If DEBUG Then + ' Debug.WriteLine(command) + '#End If + batch.Execute(command) + End Using + Return dir + End If Return Nothing + Catch ex As Exception + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{ToStringForLog()}: GetDataFromGalleryDL({command})") End Try End Function + Private Function GetTimelineFromGalleryDL(ByVal Cache As CacheKeeper, ByVal Token As CancellationToken) As SFile + Dim command$ = String.Empty + Try + Dim conf As SFile = $"{Cache.NewPath.PathWithSeparator}TwitterGdlConfig.conf" + Dim confText$ = "{""extractor"":{""cookies"": """ & MySettings.CookiesNetscapeFile.ToString.Replace("\", "/") & + """,""cookies-update"": false,""twitter"":{""cards"": false,""conversations"": false,""pinned"": false,""quoted"": false,""replies"": true,""retweets"": true,""strategy"": null,""text-tweets"": false,""twitpic"": false,""unique"": true,""users"": ""timeline"",""videos"": true}}}" + If conf.Exists(SFO.Path, True, EDP.ThrowException) Then TextSaver.SaveTextToFile(confText, conf) + If Not conf.Exists Then Throw New IO.FileNotFoundException("Can't find Twitter GDL config file", conf) + + command = $"""{Settings.GalleryDLFile}"" --verbose --no-download --no-skip --config ""{conf}"" --write-pages " + command &= GdlGetIdFilterString() + command &= $"https://twitter.com/search?q=from:{Name}+include:nativeretweets" + Dim dir As SFile = Cache.NewPath + dir.Exists(SFO.Path, True, EDP.ThrowException) + '#If DEBUG Then + ' Debug.WriteLine(command) + '#End If + Using tgdl As New TwitterGDL(dir, Token) With {.TempPostsList = _TempPostsList} : tgdl.Execute(command) : End Using + Return dir + Catch ex As Exception + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{ToStringForLog()}: GetTimelineFromGalleryDL({command})") + End Try + End Function + Private Function GdlGetIdFilterString() As String + Return If(_TempPostsList.Count > 0, $"--filter ""int(tweet_id) > {_TempPostsList.Last} or abort()"" ", String.Empty) + End Function #End Region #Region "ReparseMissing" Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken) + Const SinglePostPattern$ = "https://twitter.com/{0}/status/{1}" Dim rList As New List(Of Integer) Dim URL$ = String.Empty + Dim cache As CacheKeeper = Nothing Try If ContentMissingExists Then Dim m As UserMedia - Dim r$, PostDate$ + Dim PostDate$ Dim j As EContainer + Dim f As SFile + Dim i%, ii% + Dim files As List(Of SFile) + ResetFileNameProvider() + If IsSingleObjectDownload Then + cache = Settings.Cache + Else + cache = New CacheKeeper(DownloadContentDefault_GetRootDir.CSFilePS) + End If ProgressPre.ChangeMax(_ContentList.Count) - For i% = 0 To _ContentList.Count - 1 + For i = 0 To _ContentList.Count - 1 ProgressPre.Perform() If _ContentList(i).State = UStates.Missing Then m = _ContentList(i) - If Not m.Post.ID.IsEmptyString Then + If Not m.Post.ID.IsEmptyString Or (IsSingleObjectDownload And Not m.URL_BASE.IsEmptyString) Then ThrowAny(Token) - URL = String.Format(SinglePostUrl, m.Post.ID) - r = Responser.GetResponse(URL,, EDP.ReturnValue) - If Not r.IsEmptyString Then - j = JsonDocument.Parse(r) - If Not j Is Nothing Then - PostDate = String.Empty - If j.Contains("created_at") Then PostDate = j("created_at").Value Else PostDate = String.Empty - ObtainMedia(j, m.Post.ID, PostDate, UStates.Missing) - rList.Add(i) + If IsSingleObjectDownload Then + URL = m.URL_BASE + Else + URL = String.Format(SinglePostPattern, Name, m.Post.ID) + End If + f = GetDataFromGalleryDL(URL, cache, Favorite, Token) + If Not f.IsEmptyString Then + files = SFile.GetFiles(f, "*.txt") + If files.ListExists Then + For ii = 0 To files.Count - 1 + f = RenameGdlFile(files(ii), ii) + j = JsonDocument.Parse(f.GetText) + If Not j Is Nothing Then + With j.ItemF({"data", 0, "instructions", 0, "entries", 0, + "content", "itemContent", "tweet_results", "result", "legacy"}) + If .ListExists Then + PostDate = String.Empty + If .Contains("created_at") Then PostDate = .Value("created_at") Else PostDate = String.Empty + ObtainMedia(.Self, m.Post.ID, PostDate, UStates.Missing) + rList.Add(i) + End If + End With + j.Dispose() + End If + Next + files.Clear() End If End If End If @@ -362,6 +484,7 @@ Namespace API.Twitter Catch ex As Exception ProcessException(ex, Token, $"ReparseMissing error [{URL}]") Finally + If Not cache Is Nothing And Not IsSingleObjectDownload Then cache.Dispose() If rList.Count > 0 Then For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(i) : Next rList.Clear() @@ -371,15 +494,8 @@ Namespace API.Twitter #End Region #Region "DownloadSingleObject" Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken) - Dim PostID$ = RegexReplace(Data.URL, RParams.DM("(?<=/)\d+", 0)) - If Not PostID.IsEmptyString Then - Dim r$ = Responser.GetResponse(String.Format(SinglePostUrl, PostID),, EDP.ReturnValue) - If Not r.IsEmptyString Then - Using j As EContainer = JsonDocument.Parse(r) - If j.ListExists Then ObtainMedia(j, j.Value("id"), j.Value("created_at")) - End Using - End If - End If + _ContentList.Add(New UserMedia(Data.URL) With {.State = UStates.Missing}) + ReparseMissing(Token) End Sub #End Region #Region "Picture options" @@ -459,26 +575,7 @@ Namespace API.Twitter #Region "Exception" Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False, Optional ByVal EObj As Object = Nothing) As Integer - If AEquals(EObj, VALIDATE_MD5_ERROR) Then - If Not FromPE Then LogError(ex, Message) - Return 0 - Else - With Responser - If .StatusCode = HttpStatusCode.NotFound Then - UserExists = False - ElseIf .StatusCode = HttpStatusCode.Unauthorized Then - UserSuspended = True - ElseIf .StatusCode = HttpStatusCode.BadRequest Then - MyMainLOG = "Twitter has invalid credentials" - ElseIf .StatusCode = HttpStatusCode.ServiceUnavailable Or .StatusCode = HttpStatusCode.InternalServerError Then - MyMainLOG = $"[{CInt(.StatusCode)}] Twitter is currently unavailable ({ToString()})" - Else - If Not FromPE Then LogError(ex, Message) : HasError = True - Return 0 - End If - End With - End If - Return 1 + Return 0 End Function #End Region #Region "IDisposable support" diff --git a/SCrawler/Download/DownloadProgress.vb b/SCrawler/Download/DownloadProgress.vb index d00973e..9386d6d 100644 --- a/SCrawler/Download/DownloadProgress.vb +++ b/SCrawler/Download/DownloadProgress.vb @@ -196,8 +196,10 @@ Namespace DownloadObjects End If End Sub Private Sub JobProgress_Progress0Changed(ByVal Sender As Object, ByVal e As ProgressEventArgs) - MainProgress.Value0 = DirectCast(Sender, MyProgressExt).Value0 - MainProgress.Perform0(0) + If Not Job.Type = Download.SavedPosts Then + MainProgress.Value0 = DirectCast(Sender, MyProgressExt).Value0 + MainProgress.Perform0(0) + End If End Sub #End Region #Region "IDisposable Support" diff --git a/SCrawler/Download/STDownloader/VideoDownloaderForm.vb b/SCrawler/Download/STDownloader/VideoDownloaderForm.vb index 88d6118..813c339 100644 --- a/SCrawler/Download/STDownloader/VideoDownloaderForm.vb +++ b/SCrawler/Download/STDownloader/VideoDownloaderForm.vb @@ -43,7 +43,7 @@ Namespace DownloadObjects.STDownloader Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "VideoListForm.LoadData_GetFiles", New List(Of IYouTubeMediaContainer)) End Try End Function - Protected Overrides Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs) + Protected Overrides Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs) Handles BTT_ADD_URLS_ARR.KeyClick Dim __tag$ = UniversalFunctions.IfNullOrEmpty(Of Object)(Sender.Tag, String.Empty) If Not __tag = "a" And Not __tag = UrlsArrTag Then MyBase.BTT_ADD_KeyClick(Sender, e) @@ -51,6 +51,7 @@ Namespace DownloadObjects.STDownloader Dim url$ = String.Empty Try url = BufferText + Dim disableDown As Boolean = e.Shift Dim output As SFile = Settings.LatestSavingPath Dim isArr As Boolean = __tag = UrlsArrTag Dim formOpened As Boolean = False @@ -152,7 +153,7 @@ Namespace DownloadObjects.STDownloader If media Is Nothing Then MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical) Else - ControlCreateAndAdd(media) + ControlCreateAndAdd(media, disableDown) End If End If Catch ex As Exception diff --git a/SCrawler/Editors/GlobalSettingsForm.Designer.vb b/SCrawler/Editors/GlobalSettingsForm.Designer.vb index f9c4563..8adcac7 100644 --- a/SCrawler/Editors/GlobalSettingsForm.Designer.vb +++ b/SCrawler/Editors/GlobalSettingsForm.Designer.vb @@ -122,6 +122,8 @@ Namespace Editors Me.CH_NAME_SITE_FRIENDLY = New System.Windows.Forms.CheckBox() Me.CH_STD = New System.Windows.Forms.CheckBox() Me.CH_STD_EVERY = New System.Windows.Forms.CheckBox() + Me.CH_STD_YT_LOAD = New System.Windows.Forms.CheckBox() + Me.CH_STD_YT_REMOVE = New System.Windows.Forms.CheckBox() Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox() @@ -157,8 +159,7 @@ Namespace Editors Me.TAB_MAIN = New System.Windows.Forms.TabControl() Me.TAB_ENVIR = New System.Windows.Forms.TabPage() Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() - Me.CH_STD_YT_LOAD = New System.Windows.Forms.CheckBox() - Me.CH_STD_YT_REMOVE = New System.Windows.Forms.CheckBox() + Me.CH_UICON_UP = New System.Windows.Forms.CheckBox() TP_BASIS = New System.Windows.Forms.TableLayoutPanel() TP_IMAGES = New System.Windows.Forms.TableLayoutPanel() TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel() @@ -508,13 +509,13 @@ Namespace Editors TP_FILE_NAME.Controls.Add(Me.OPT_FILE_NAME_ADD_DATE, 2, 0) TP_FILE_NAME.Controls.Add(Me.CH_FILE_NAME_CHANGE, 0, 0) TP_FILE_NAME.Dock = System.Windows.Forms.DockStyle.Fill - TP_FILE_NAME.Location = New System.Drawing.Point(1, 53) + TP_FILE_NAME.Location = New System.Drawing.Point(1, 79) TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0) TP_FILE_NAME.Name = "TP_FILE_NAME" TP_FILE_NAME.RowCount = 1 TP_FILE_NAME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FILE_NAME.Size = New System.Drawing.Size(574, 30) - TP_FILE_NAME.TabIndex = 2 + TP_FILE_NAME.TabIndex = 3 ' 'OPT_FILE_NAME_REPLACE ' @@ -566,14 +567,14 @@ Namespace Editors TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_START, 3, 0) TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_END, 4, 0) TP_FILE_PATTERNS.Dock = System.Windows.Forms.DockStyle.Fill - TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 84) + TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 110) TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0) TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS" TP_FILE_PATTERNS.RowCount = 1 TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29.0!)) TP_FILE_PATTERNS.Size = New System.Drawing.Size(574, 30) - TP_FILE_PATTERNS.TabIndex = 3 + TP_FILE_PATTERNS.TabIndex = 4 ' 'CH_FILE_DATE ' @@ -880,10 +881,10 @@ Namespace Editors ' Me.CH_DOWN_REPARSE_MISSING.AutoSize = True Me.CH_DOWN_REPARSE_MISSING.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 202) + Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 228) Me.CH_DOWN_REPARSE_MISSING.Name = "CH_DOWN_REPARSE_MISSING" Me.CH_DOWN_REPARSE_MISSING.Size = New System.Drawing.Size(568, 19) - Me.CH_DOWN_REPARSE_MISSING.TabIndex = 7 + Me.CH_DOWN_REPARSE_MISSING.TabIndex = 8 Me.CH_DOWN_REPARSE_MISSING.Text = "Trying to download missing posts using regular download" TT_MAIN.SetToolTip(Me.CH_DOWN_REPARSE_MISSING, "If missing posts exist, the missing posts will attempt to be downloaded via user " & "download") @@ -925,6 +926,34 @@ Namespace Editors TT_MAIN.SetToolTip(Me.CH_STD_EVERY, "Show notifications when download in standalone downloader is complete") Me.CH_STD_EVERY.UseVisualStyleBackColor = True ' + 'CH_STD_YT_LOAD + ' + Me.CH_STD_YT_LOAD.AutoSize = True + Me.CH_STD_YT_LOAD.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_STD_YT_LOAD.Location = New System.Drawing.Point(4, 166) + Me.CH_STD_YT_LOAD.Name = "CH_STD_YT_LOAD" + Me.CH_STD_YT_LOAD.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) + Me.CH_STD_YT_LOAD.Size = New System.Drawing.Size(568, 19) + Me.CH_STD_YT_LOAD.TabIndex = 6 + Me.CH_STD_YT_LOAD.Text = "Load downloaded YouTube videos to the form" + TT_MAIN.SetToolTip(Me.CH_STD_YT_LOAD, "If checked, downloaded YouTube videos will be loaded to the form. Otherwise, all " & + "downloaded data will be loaded to the form except YouTube data.") + Me.CH_STD_YT_LOAD.UseVisualStyleBackColor = True + ' + 'CH_STD_YT_REMOVE + ' + Me.CH_STD_YT_REMOVE.AutoSize = True + Me.CH_STD_YT_REMOVE.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_STD_YT_REMOVE.Location = New System.Drawing.Point(4, 192) + Me.CH_STD_YT_REMOVE.Name = "CH_STD_YT_REMOVE" + Me.CH_STD_YT_REMOVE.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) + Me.CH_STD_YT_REMOVE.Size = New System.Drawing.Size(568, 19) + Me.CH_STD_YT_REMOVE.TabIndex = 7 + Me.CH_STD_YT_REMOVE.Text = "Clear YouTube videos when clearing the list" + TT_MAIN.SetToolTip(Me.CH_STD_YT_REMOVE, "If checked, YouTube videos will also be removed from the list. This action will a" & + "lso affect the standalone 'YouTubeDownloader' app.") + Me.CH_STD_YT_REMOVE.UseVisualStyleBackColor = True + ' 'TP_CHANNELS_IMGS ' TP_CHANNELS_IMGS.ColumnCount = 2 @@ -1265,18 +1294,20 @@ Namespace Editors TP_DOWNLOADING.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] TP_DOWNLOADING.ColumnCount = 1 TP_DOWNLOADING.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 2) - TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 3) - TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 4) + TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 3) + TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 4) + TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 5) TP_DOWNLOADING.Controls.Add(Me.CH_UDESCR_UP, 0, 0) - TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 5) - TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 6) - TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 7) + TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 6) + TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 7) + TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 8) TP_DOWNLOADING.Controls.Add(Me.CH_UNAME_UP, 0, 1) + TP_DOWNLOADING.Controls.Add(Me.CH_UICON_UP, 0, 2) TP_DOWNLOADING.Dock = System.Windows.Forms.DockStyle.Fill TP_DOWNLOADING.Location = New System.Drawing.Point(0, 0) TP_DOWNLOADING.Name = "TP_DOWNLOADING" - TP_DOWNLOADING.RowCount = 9 + TP_DOWNLOADING.RowCount = 10 + TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!)) @@ -1305,12 +1336,12 @@ Namespace Editors Me.TXT_SCRIPT.CaptionWidth = 120.0R Me.TXT_SCRIPT.ChangeControlsEnableOnCheckedChange = False Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 118) + Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 144) Me.TXT_SCRIPT.Name = "TXT_SCRIPT" Me.TXT_SCRIPT.PlaceholderEnabled = True Me.TXT_SCRIPT.PlaceholderText = "Enter script path here..." Me.TXT_SCRIPT.Size = New System.Drawing.Size(568, 22) - Me.TXT_SCRIPT.TabIndex = 4 + Me.TXT_SCRIPT.TabIndex = 5 ' 'TXT_DOWN_COMPLETE_SCRIPT ' @@ -1320,12 +1351,12 @@ Namespace Editors Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionToolTipText = "This command will be executed after all downloads are completed" Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionWidth = 120.0R Me.TXT_DOWN_COMPLETE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 147) + Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 173) Me.TXT_DOWN_COMPLETE_SCRIPT.Name = "TXT_DOWN_COMPLETE_SCRIPT" Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderEnabled = True Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderText = "Enter command here..." Me.TXT_DOWN_COMPLETE_SCRIPT.Size = New System.Drawing.Size(568, 22) - Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 5 + Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 6 ' 'TP_MISSING_DATA ' @@ -1336,14 +1367,14 @@ Namespace Editors TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_TO_LOG, 0, 0) TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_ERROS_TO_LOG, 1, 0) TP_MISSING_DATA.Dock = System.Windows.Forms.DockStyle.Fill - TP_MISSING_DATA.Location = New System.Drawing.Point(1, 173) + TP_MISSING_DATA.Location = New System.Drawing.Point(1, 199) TP_MISSING_DATA.Margin = New System.Windows.Forms.Padding(0) TP_MISSING_DATA.Name = "TP_MISSING_DATA" TP_MISSING_DATA.RowCount = 1 TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24.0!)) TP_MISSING_DATA.Size = New System.Drawing.Size(574, 25) - TP_MISSING_DATA.TabIndex = 6 + TP_MISSING_DATA.TabIndex = 7 ' 'CH_UNAME_UP ' @@ -1352,7 +1383,7 @@ Namespace Editors Me.CH_UNAME_UP.Location = New System.Drawing.Point(4, 30) Me.CH_UNAME_UP.Name = "CH_UNAME_UP" Me.CH_UNAME_UP.Size = New System.Drawing.Size(568, 19) - Me.CH_UNAME_UP.TabIndex = 7 + Me.CH_UNAME_UP.TabIndex = 1 Me.CH_UNAME_UP.Text = "Update user site name every time" Me.CH_UNAME_UP.UseVisualStyleBackColor = True ' @@ -1843,33 +1874,16 @@ Namespace Editors Me.CONTAINER_MAIN.TabIndex = 0 Me.CONTAINER_MAIN.TopToolStripPanelVisible = False ' - 'CH_STD_YT_LOAD + 'CH_UICON_UP ' - Me.CH_STD_YT_LOAD.AutoSize = True - Me.CH_STD_YT_LOAD.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_STD_YT_LOAD.Location = New System.Drawing.Point(4, 166) - Me.CH_STD_YT_LOAD.Name = "CH_STD_YT_LOAD" - Me.CH_STD_YT_LOAD.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) - Me.CH_STD_YT_LOAD.Size = New System.Drawing.Size(568, 19) - Me.CH_STD_YT_LOAD.TabIndex = 6 - Me.CH_STD_YT_LOAD.Text = "Load downloaded YouTube videos to the form" - TT_MAIN.SetToolTip(Me.CH_STD_YT_LOAD, "If checked, downloaded YouTube videos will be loaded to the form. Otherwise, all " & - "downloaded data will be loaded to the form except YouTube data.") - Me.CH_STD_YT_LOAD.UseVisualStyleBackColor = True - ' - 'CH_STD_YT_REMOVE - ' - Me.CH_STD_YT_REMOVE.AutoSize = True - Me.CH_STD_YT_REMOVE.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_STD_YT_REMOVE.Location = New System.Drawing.Point(4, 192) - Me.CH_STD_YT_REMOVE.Name = "CH_STD_YT_REMOVE" - Me.CH_STD_YT_REMOVE.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) - Me.CH_STD_YT_REMOVE.Size = New System.Drawing.Size(568, 19) - Me.CH_STD_YT_REMOVE.TabIndex = 7 - Me.CH_STD_YT_REMOVE.Text = "Clear YouTube videos when clearing the list" - TT_MAIN.SetToolTip(Me.CH_STD_YT_REMOVE, "If checked, YouTube videos will also be removed from the list. This action will a" & - "lso affect the standalone 'YouTubeDownloader' app.") - Me.CH_STD_YT_REMOVE.UseVisualStyleBackColor = True + Me.CH_UICON_UP.AutoSize = True + Me.CH_UICON_UP.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_UICON_UP.Location = New System.Drawing.Point(4, 56) + Me.CH_UICON_UP.Name = "CH_UICON_UP" + Me.CH_UICON_UP.Size = New System.Drawing.Size(568, 19) + Me.CH_UICON_UP.TabIndex = 2 + Me.CH_UICON_UP.Text = "Update user icon and banner every time (where supported)" + Me.CH_UICON_UP.UseVisualStyleBackColor = True ' 'GlobalSettingsForm ' @@ -2041,5 +2055,6 @@ Namespace Editors Private WithEvents CH_STD_UPDATE_YT_PATH As CheckBox Private WithEvents CH_STD_YT_LOAD As CheckBox Private WithEvents CH_STD_YT_REMOVE As CheckBox + Private WithEvents CH_UICON_UP As CheckBox End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/GlobalSettingsForm.vb b/SCrawler/Editors/GlobalSettingsForm.vb index 4ec9476..34d205c 100644 --- a/SCrawler/Editors/GlobalSettingsForm.vb +++ b/SCrawler/Editors/GlobalSettingsForm.vb @@ -89,6 +89,7 @@ Namespace Editors 'Downloading CH_UDESCR_UP.Checked = .UpdateUserDescriptionEveryTime CH_UNAME_UP.Checked = .UserSiteNameUpdateEveryTime + CH_UICON_UP.Checked = .UpdateUserIconBannerEveryTime TXT_SCRIPT.Checked = .ScriptData.Attribute TXT_SCRIPT.Text = .ScriptData.Value TXT_DOWN_COMPLETE_SCRIPT.Text = .DownloadsCompleteCommand @@ -244,6 +245,7 @@ Namespace Editors 'Downloading .UpdateUserDescriptionEveryTime.Value = CH_UDESCR_UP.Checked .UserSiteNameUpdateEveryTime.Value = CH_UNAME_UP.Checked + .UpdateUserIconBannerEveryTime.Value = CH_UICON_UP.Checked .ScriptData.Value = TXT_SCRIPT.Text .ScriptData.Attribute.Value = TXT_SCRIPT.Checked .DownloadsCompleteCommand.Value = TXT_DOWN_COMPLETE_SCRIPT.Text diff --git a/SCrawler/Editors/UsersInfoForm.vb b/SCrawler/Editors/UsersInfoForm.vb index 13823b3..2f26053 100644 --- a/SCrawler/Editors/UsersInfoForm.vb +++ b/SCrawler/Editors/UsersInfoForm.vb @@ -492,13 +492,23 @@ Namespace Editors If Not info.IsEmptyString Then MsgBoxE({info, "User information"}) End Sub Private Sub CONTEXT_BTT_OPEN_FOLDER_Click(sender As Object, e As EventArgs) Handles CONTEXT_BTT_OPEN_FOLDER.Click - Dim u As UserOpt = GetUserFromList() - If Not u Is Nothing Then u.User.OpenFolder() + OpenUserFolder() End Sub Private Sub CONTEXT_BTT_OPEN_SITE_Click(sender As Object, e As EventArgs) Handles CONTEXT_BTT_OPEN_SITE.Click Dim u As UserOpt = GetUserFromList() If Not u Is Nothing Then u.User.OpenSite() End Sub +#End Region +#Region "List handlers" + Private Sub LIST_DATA_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LIST_DATA.MouseDoubleClick + OpenUserFolder() + End Sub +#End Region +#Region "Functions" + Private Sub OpenUserFolder() + Dim u As UserOpt = GetUserFromList() + If Not u Is Nothing Then u.User.OpenFolder() + End Sub #End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/ListImagesLoader.vb b/SCrawler/ListImagesLoader.vb index 5143e14..4c3effb 100644 --- a/SCrawler/ListImagesLoader.vb +++ b/SCrawler/ListImagesLoader.vb @@ -122,6 +122,8 @@ Friend Class ListImagesLoader UserDataList.Clear() UpdateInProgress = False End If + Else + UpdateInProgress = False End If Else Dim t As New List(Of Task) diff --git a/SCrawler/MainFrame.Designer.vb b/SCrawler/MainFrame.Designer.vb index ff4c00e..627c115 100644 --- a/SCrawler/MainFrame.Designer.vb +++ b/SCrawler/MainFrame.Designer.vb @@ -125,6 +125,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Me.BTT_TRAY_SHOW_HIDE = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_TRAY_CLOSE = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_TRAY_CLOSE_NO_SCRIPT = New System.Windows.Forms.ToolStripMenuItem() + Me.BTT_TRAY_DOWNLOADER = 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() @@ -826,9 +827,9 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form ' 'TRAY_CONTEXT ' - Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_PAUSE_AUTOMATION, Me.BTT_TRAY_SILENT_MODE, Me.BTT_TRAY_FEED_SHOW, Me.BTT_TRAY_CHANNELS, TRAY_SEP_1, Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_2, Me.BTT_TRAY_CLOSE, Me.BTT_TRAY_CLOSE_NO_SCRIPT}) + Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_PAUSE_AUTOMATION, Me.BTT_TRAY_SILENT_MODE, Me.BTT_TRAY_FEED_SHOW, Me.BTT_TRAY_CHANNELS, Me.BTT_TRAY_DOWNLOADER, TRAY_SEP_1, Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_2, Me.BTT_TRAY_CLOSE, Me.BTT_TRAY_CLOSE_NO_SCRIPT}) Me.TRAY_CONTEXT.Name = "TRAY_CONTEXT" - Me.TRAY_CONTEXT.Size = New System.Drawing.Size(171, 170) + Me.TRAY_CONTEXT.Size = New System.Drawing.Size(171, 192) ' 'BTT_TRAY_PAUSE_AUTOMATION ' @@ -892,6 +893,13 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Me.BTT_TRAY_CLOSE_NO_SCRIPT.ToolTipText = "Close the program without executing the script" Me.BTT_TRAY_CLOSE_NO_SCRIPT.Visible = False ' + 'BTT_TRAY_DOWNLOADER + ' + Me.BTT_TRAY_DOWNLOADER.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24 + Me.BTT_TRAY_DOWNLOADER.Name = "BTT_TRAY_DOWNLOADER" + Me.BTT_TRAY_DOWNLOADER.Size = New System.Drawing.Size(170, 22) + Me.BTT_TRAY_DOWNLOADER.Text = "Downloader" + ' 'MainFrame ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -996,4 +1004,5 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Private WithEvents BTT_TRAY_FEED_SHOW As ToolStripMenuItem Friend WithEvents MENU_DOWN_ALL As ToolStripDropDownButton Private WithEvents BTT_TRAY_CHANNELS As ToolStripMenuItem + Private WithEvents BTT_TRAY_DOWNLOADER As ToolStripMenuItem End Class \ No newline at end of file diff --git a/SCrawler/MainFrame.vb b/SCrawler/MainFrame.vb index 549452f..e6b4ec4 100644 --- a/SCrawler/MainFrame.vb +++ b/SCrawler/MainFrame.vb @@ -452,9 +452,9 @@ CloseResume: Downloader.AddRange(Settings.GetUsers(UserExistsPredicate), e.IncludeInTheFeed) End Sub Private Sub BTT_DOWN_SITE_FULL_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_SITE_FULL.KeyClick - DownloadSiteFull(False, e.IncludeInTheFeed) + DownloadSiteFull(False, e.IncludeInTheFeed, e.Shift) End Sub - Private Sub DownloadSiteFull(ByVal ReadyForDownloadOnly As Boolean, ByVal IncludeInTheFeed As Boolean) + Private Sub DownloadSiteFull(ByVal ReadyForDownloadOnly As Boolean, ByVal IncludeInTheFeed As Boolean, Optional ByVal IgnoreExists As Boolean = False) Using f As New SiteSelectionForm(Settings.LatestDownloadedSites.ValuesList) f.ShowDialog() If f.DialogResult = DialogResult.OK Then @@ -462,7 +462,7 @@ CloseResume: Settings.LatestDownloadedSites.AddRange(f.SelectedSites) Settings.LatestDownloadedSites.Update() If f.SelectedSites.Count > 0 Then - Downloader.AddRange(Settings.GetUsers(Function(u) f.SelectedSites.Contains(u.Site) And u.Exists And + Downloader.AddRange(Settings.GetUsers(Function(u) f.SelectedSites.Contains(u.Site) And (u.Exists Or IgnoreExists) And (Not ReadyForDownloadOnly Or u.ReadyForDownload)), IncludeInTheFeed) End If End If @@ -513,7 +513,7 @@ CloseResume: TrayIcon.ContextMenuStrip.Hide() MainFrameObj.PauseButtons.UpdatePauseButtons() End Sub - Private Sub BTT_DOWN_VIDEO_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_VIDEO.Click + Private Sub BTT_DOWN_VIDEO_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_VIDEO.Click, BTT_TRAY_DOWNLOADER.Click VideoDownloader.FormShow() End Sub Private Sub BTT_DOWN_STOP_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_STOP.Click diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb index a880f13..6fd0f1f 100644 --- a/SCrawler/My Project/AssemblyInfo.vb +++ b/SCrawler/My Project/AssemblyInfo.vb @@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices ' by using the '*' as shown below: ' - - + + diff --git a/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb b/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb index 77aa65c..778393a 100644 --- a/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb @@ -23,6 +23,15 @@ Namespace Plugin.Hosts End Property Friend Property Instance As UserDataBase Friend ReadOnly Property ExternalSource As IDownloadableMedia = Nothing + Public Overrides ReadOnly Property Exists As Boolean + Get + If SiteKey = API.YouTube.YouTubeSiteKey Then + Return MyBase.Exists + Else + Return _Exists + End If + End Get + End Property Public Overrides Property File As SFile Get Return _File @@ -128,7 +137,7 @@ Namespace Plugin.Hosts End Sub Public Overrides Sub Load(ByVal f As SFile) MyBase.Load(f) - If _Exists Then _Exists = File.Exists + If _Exists Then _Exists = Not MediaState = UserMediaStates.Downloaded OrElse File.Exists End Sub Public Overrides Sub Save() If FileSettings.IsEmptyString Then @@ -142,6 +151,9 @@ Namespace Plugin.Hosts x.Save(FileSettings) End Using End Sub + Public Overrides Function GetHashCode() As Integer + Return URL.GetHashCode + End Function Protected Overrides Sub Dispose(ByVal disposing As Boolean) If Not disposedValue And disposing Then Instance.DisposeIfReady() : ExternalSource.DisposeIfReady(False) MyBase.Dispose(disposing) diff --git a/SCrawler/SettingsCLS.vb b/SCrawler/SettingsCLS.vb index 0f982c2..baddf2e 100644 --- a/SCrawler/SettingsCLS.vb +++ b/SCrawler/SettingsCLS.vb @@ -238,6 +238,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable FromChannelDownloadTopUse = New XMLValue(Of Boolean)("FromChannelDownloadTopUse", False, MyXML, n) FromChannelCopyImageToUser = New XMLValue(Of Boolean)("FromChannelCopyImageToUser", True, MyXML, n) UpdateUserDescriptionEveryTime = New XMLValue(Of Boolean)("UpdateUserDescriptionEveryTime", True, MyXML, n) + UpdateUserIconBannerEveryTime = New XMLValue(Of Boolean)("UpdateUserIconBannerEveryTime", True, MyXML, n) ScriptData = New XMLValueAttribute(Of String, Boolean)("ScriptData", "Use",,, MyXML, n) n = {"Users", "FileName"} @@ -720,6 +721,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable Friend ReadOnly Property FromChannelDownloadTopUse As XMLValue(Of Boolean) Friend ReadOnly Property FromChannelCopyImageToUser As XMLValue(Of Boolean) Friend ReadOnly Property UpdateUserDescriptionEveryTime As XMLValue(Of Boolean) + Friend ReadOnly Property UpdateUserIconBannerEveryTime As XMLValue(Of Boolean) #Region "File naming" Friend ReadOnly Property FileAddDateToFileName As XMLValue(Of Boolean) Friend ReadOnly Property FileAddTimeToFileName As XMLValue(Of Boolean)