diff --git a/Changelog.md b/Changelog.md index 862f78d..fd524a0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,28 @@ +# 2024.10.24.0 + +*2024-10-24* + +- Added + - YouTube (standalone app) + - settings `Embed thumbnail (cover)` and `Allow webm formats` + - changed cover selection for music downloads + - allow `webm` formats is there are no `mp4` formats via http protocol (issue #211) + - Sites: + - Instagram + - **ability to manually change username** + - **mark user as non-existent if user `ID` cannot be obtained** + - Twitter: **ability to manually change username** + - Main window: add users search button to 'Info' menu + - Minor improvements +- Updated + - yt-dlp up to version **2024.10.22** + - gallery-dl up to version **1.27.6** +- Fixed + - YouTube (standalone app): adding incorrect playlist lines + - Reddit: incorrect UNIX date parsing + - Can't change data path (issue #206) + - Minor bugs + # 2024.9.2.0 *2024-09-02* diff --git a/FAQ.md b/FAQ.md index b2f1b34..929d977 100644 --- a/FAQ.md +++ b/FAQ.md @@ -26,7 +26,7 @@ I strongly recommend you to **regularly** create backup copies of the settings f # Most frequently questions about SCrawler -**Is something doesn't download, always check the [SITE'S REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements) before asking questions!** +**If something doesn't download, always check the [SITE'S REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements) before asking questions!** *How to use: find your problem in the list and read the answer.* diff --git a/SCrawler.YouTube/Base/YouTubeSettings.vb b/SCrawler.YouTube/Base/YouTubeSettings.vb index a60c6e5..ca38164 100644 --- a/SCrawler.YouTube/Base/YouTubeSettings.vb +++ b/SCrawler.YouTube/Base/YouTubeSettings.vb @@ -311,6 +311,9 @@ Namespace API.YouTube.Base Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer) + + Public ReadOnly Property DefaultVideoAllowWebm As XMLValue(Of Boolean) Public ReadOnly Property DefaultVideoConvertNonAVC As XMLValue(Of Boolean) @@ -416,6 +419,9 @@ Namespace API.YouTube.Base Public ReadOnly Property DefaultAudioEmbedThumbnail As XMLValue(Of Boolean) + + Public ReadOnly Property DefaultAudioEmbedThumbnail_Cover As XMLValue(Of Boolean) Public ReadOnly Property DefaultAudioEmbedThumbnail_ExtractedFiles As XMLValue(Of Boolean) diff --git a/SCrawler.YouTube/Declarations.vb b/SCrawler.YouTube/Declarations.vb index 736ec3e..ac6aff2 100644 --- a/SCrawler.YouTube/Declarations.vb +++ b/SCrawler.YouTube/Declarations.vb @@ -59,6 +59,7 @@ Namespace API.YouTube Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue) Friend ReadOnly MusicUrlApply As RParams = RParams.DMS("https://([w\.]*)youtube.com.+", 1, RegexReturn.Replace, EDP.ReturnValue, CType(Function(input$) "music.", Func(Of String, String)), String.Empty) + Friend ReadOnly M3U8ExcludedSymbols As String() = {".", ",", ":", "/", "\", "(", ")", "[", "]"} Friend Function ToMusicUrl(ByVal URL As String, ByVal IsMusic As Boolean) As String Try : Return If(IsMusic And Not URL.IsEmptyString, CStr(RegexReplace(URL, MusicUrlApply)).IfNullOrEmpty(URL), URL) : Catch : Return URL : End Try End Function diff --git a/SCrawler.YouTube/My Project/AssemblyInfo.vb b/SCrawler.YouTube/My Project/AssemblyInfo.vb index 366885b..2696598 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 fb2a656..e805ac7 100644 --- a/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb +++ b/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb @@ -175,7 +175,9 @@ Namespace API.YouTube.Objects Protected _ThumbnailUrl As String = String.Empty Public Overridable Property ThumbnailUrl As String Implements IDownloadableMedia.ThumbnailUrl Get - If _ThumbnailUrl.IsEmptyString And Thumbnails.Count > 0 Then + If Not CoverURL.IsEmptyString Then + Return CoverURL + ElseIf _ThumbnailUrl.IsEmptyString And Thumbnails.Count > 0 Then Return Thumbnails.FirstOrDefault.URL Else Return _ThumbnailUrl @@ -904,7 +906,8 @@ Namespace API.YouTube.Objects Const m3u8DataRow$ = "#EXTINF:{0},{1}" & vbCrLf & "{2}" With Element Dim f As SFile = __file.IfNullOrEmpty(.File) - Dim __f$ = SymbolsConverter.ASCII.EncodeSymbolsOnly(If(Mode = M3U8CreationMode.Absolute, f.ToString, f.File)) + Dim fStr$ = f.ToString.StringReplaceSymbols({"\"}, "/", EDP.ReturnValue) + Dim __f$ = SymbolsConverter.ASCII.Extended.EncodeSymbolsOnly(If(Mode = M3U8CreationMode.Absolute, fStr, f.File), M3U8ExcludedSymbols) If Mode = M3U8CreationMode.Absolute Then __f = $"file:///{__f}" Dim fName$ = .Title.IfNullOrEmpty(f.Name) If MyYouTubeSettings.MusicPlaylistCreate_M3U8_AppendNumber And .PlaylistIndex > 0 Then fName = $"{ .PlaylistIndex}. {fName}" @@ -1022,12 +1025,19 @@ Namespace API.YouTube.Objects End If Dim cDown As Boolean = False + Dim fCover As SFile = Nothing + Dim cUrl$ = String.Empty For Each elem In Elements With DirectCast(elem, YouTubeMediaContainerBase) - If Not .CoverDownloaded Then .CoverDownloaded = cDown + 'If Not .CoverDownloaded Then .CoverDownloaded = cDown + .CoverDownloaded = cDown + .CoverFile = fCover + .CoverURL = cUrl AddHandler .FileDownloadStarted, fDown .Download(UseCookies, Token) cDown = .CoverDownloaded + fCover = .CoverFile + cUrl = .CoverURL RemoveHandler .FileDownloadStarted, fDown End With If Token.IsCancellationRequested Or disposedValue Then Exit For @@ -1054,6 +1064,8 @@ Namespace API.YouTube.Objects End Try End Sub Protected CoverDownloaded As Boolean = False + Protected CoverFile As SFile = Nothing + Protected CoverURL As String = String.Empty Private Sub DownloadPlaylistCover(ByVal PlsId As String, ByVal f As SFile, ByVal UseCookies As Boolean) Try Dim url$ = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={PlsId}" @@ -1089,7 +1101,8 @@ Namespace API.YouTube.Objects url = LinkFormatterSecure(u) f.Name = "cover" f.Extension = "jpg" - If resp.DownloadFile(url, f, EDP.ReturnValue) And f.Exists Then CoverDownloaded = True : AddFile(f) + If resp.DownloadFile(url, f, EDP.ReturnValue) And f.Exists Then _ + CoverFile = f : CoverURL = url : CoverDownloaded = True : AddFile(f) End If End If End Using @@ -1270,10 +1283,10 @@ Namespace API.YouTube.Objects End Sub Dim embedThumbTo As Action(Of SFile) = Sub(ByVal dFile As SFile) - If dFile.Exists And ThumbnailFile.Exists Then + If dFile.Exists And CoverFile.IfNullOrEmpty(ThumbnailFile).Exists Then Dim dFileNew As SFile = dFile dFileNew.Name &= "_NEW" - .Execute($"ffmpeg -i ""{dFile}"" -i ""{ThumbnailFile}"" -map 0:0 -map 1:0 -c copy -id3v2_version 3 -metadata:s:v title=""Cover"" -metadata:s:v comment=""Cover"" ""{dFileNew}""") + .Execute($"ffmpeg -i ""{dFile}"" -i ""{CoverFile.IfNullOrEmpty(ThumbnailFile)}"" -map 0:0 -map 1:0 -c copy -id3v2_version 3 -metadata:s:v title=""Cover"" -metadata:s:v comment=""Cover"" ""{dFileNew}""") If dFileNew.Exists AndAlso dFile.Delete(,, EDP.ReturnValue) Then SFile.Rename(dFileNew, dFile) End If End Sub @@ -1353,6 +1366,10 @@ Namespace API.YouTube.Objects End If End If + 'mp3 + If IsMusic And ObjectType = YouTubeMediaType.Single And File.Extension = mp3 And + Not mp3ThumbEmbedded And CoverFile.Exists And MyYouTubeSettings.DefaultAudioEmbedThumbnail_Cover Then embedThumbTo.Invoke(File) + 'Update video ThrowAny(Token) If SelectedVideoIndex >= 0 AndAlso tempFilesList.Count > 0 AndAlso tempFilesList.Exists(Function(tf) tf.ToReplace) Then @@ -1725,6 +1742,7 @@ Namespace API.YouTube.Objects Dim obj As MediaObject Dim nValue# Dim sValue$ + Dim allowWebm As Boolean = MyYouTubeSettings.DefaultVideoAllowWebm Dim validCodecValue As Func(Of String, Boolean) = Function(codec) Not codec.IsEmptyString AndAlso Not codec = "none" For Each ee In e({"formats"}) @@ -1775,12 +1793,13 @@ Namespace API.YouTube.Objects Dim d As MediaObject = Nothing Dim expWebm As Predicate(Of MediaObject) = Function(mo) mo.Extension = webm Dim expAVC As Predicate(Of MediaObject) = Function(mo) mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc) - Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean) = - Function(mo, exp, isTrue) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width - Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False) - Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True) - Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True) - Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False) + Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean, Boolean) = + Function(mo, exp, isTrue, checkHttp) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width And + (Not checkHttp OrElse mo.ProtocolType = Protocols.https) + Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False, allowWebm) + Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True, allowWebm) + Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True, False) + Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False, False) For Each d In data If MediaObjects.Count = 0 Then Exit For If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm) diff --git a/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb b/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb index ef74db4..708032d 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/DeclaredNames.vb b/SCrawler/API/Base/DeclaredNames.vb index 34af8da..456c42b 100644 --- a/SCrawler/API/Base/DeclaredNames.vb +++ b/SCrawler/API/Base/DeclaredNames.vb @@ -28,6 +28,8 @@ Namespace API.Base Friend Const GifsDownloadCaption As String = "Download GIFs" Friend Const UseMD5ComparisonCaption As String = "Use MD5 comparison" Friend Const UseMD5ComparisonToolTip As String = "Each image will be checked for existence using MD5" + Friend Const UserNameChangeCaption As String = "UserName" + Friend Const UserNameChangeToolTip As String = "If the user has changed their UserName, you can set a new name here. Not required for new users." Private Sub New() End Sub End Class diff --git a/SCrawler/API/Base/UserDataBase.vb b/SCrawler/API/Base/UserDataBase.vb index 100421d..06b85bd 100644 --- a/SCrawler/API/Base/UserDataBase.vb +++ b/SCrawler/API/Base/UserDataBase.vb @@ -947,6 +947,9 @@ BlockNullPicture: LogError(ex, "user information loading error") End Try End Sub + Private Sub UpdateUserInformation_Ex() + If _ForceSaveUserInfoOnException Then UpdateUserInformation() + End Sub Friend Overridable Overloads Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation UpdateUserInformation(False) End Sub @@ -1117,6 +1120,7 @@ BlockNullPicture: Protected UseClientTokens As Boolean = False Protected _ForceSaveUserData As Boolean = False Protected _ForceSaveUserInfo As Boolean = False + Protected _ForceSaveUserInfoOnException As Boolean = False Private _DownloadInProgress As Boolean = False Private _EnvirUserExists As Boolean Private _EnvirUserSuspended As Boolean @@ -1136,6 +1140,7 @@ BlockNullPicture: _DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime _ForceSaveUserData = False _ForceSaveUserInfo = False + _ForceSaveUserInfoOnException = False _EnvirUserExists = UserExists _EnvirUserSuspended = UserSuspended _EnvirCreatedByChannel = CreatedByChannel @@ -1265,9 +1270,11 @@ BlockNullPicture: ThrowIfDisposed() If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated() Catch oex As OperationCanceledException When Token.IsCancellationRequested Or TokenPersonal.IsCancellationRequested Or TokenQueue.IsCancellationRequested + UpdateUserInformation_Ex() MyMainLOG = $"{ToStringForLog()}: downloading canceled" Canceled = True Catch exit_ex As ExitException + UpdateUserInformation_Ex() If Not exit_ex.Silent Then If exit_ex.SimpleLogLine Then MyMainLOG = $"{ToStringForLog()}: downloading interrupted (exit) ({exit_ex.Message})" @@ -1279,6 +1286,7 @@ BlockNullPicture: Catch dex As ObjectDisposedException When Disposed Canceled = True Catch ex As Exception + UpdateUserInformation_Ex() LogError(ex, "downloading data error") HasError = True Finally @@ -1912,6 +1920,7 @@ BlockNullPicture: If m.Contains(IUserData.EraseMode.History) Then If MyFilePosts.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True If MyFileData.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True + If MyMD5File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True LastUpdated = Nothing EraseData_AdditionalDataFiles() UpdateUserInformation() @@ -1928,6 +1937,8 @@ BlockNullPicture: _TempMediaList.Clear() _ContentNew.Clear() _ContentList.Clear() + _MD5List.Clear() + _MD5Loaded = False End If End If End If diff --git a/SCrawler/API/Instagram/EditorExchangeOptions.vb b/SCrawler/API/Instagram/EditorExchangeOptions.vb index 7de2501..d092a63 100644 --- a/SCrawler/API/Instagram/EditorExchangeOptions.vb +++ b/SCrawler/API/Instagram/EditorExchangeOptions.vb @@ -7,6 +7,7 @@ ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY Imports SCrawler.Plugin.Attributes +Imports DN = SCrawler.API.Base.DeclaredNames Namespace API.Instagram Friend Class EditorExchangeOptions #Region "Download" @@ -35,6 +36,8 @@ Namespace API.Instagram #End Region Friend Property PutImageVideoFolder As Boolean + + Friend Overridable Property UserName As String = String.Empty Friend Sub New(ByVal u As UserData) With u GetTimeline = .GetTimeline @@ -50,6 +53,8 @@ Namespace API.Instagram GetTagged_VideoPic = .GetTaggedData_VideoPic PutImageVideoFolder = .PutImageVideoFolder + + UserName = .NameTrue(True) End With End Sub Friend Sub New(ByVal s As SiteSettings) diff --git a/SCrawler/API/Instagram/UserData.vb b/SCrawler/API/Instagram/UserData.vb index 12573d1..145faa1 100644 --- a/SCrawler/API/Instagram/UserData.vb +++ b/SCrawler/API/Instagram/UserData.vb @@ -112,9 +112,9 @@ Namespace API.Instagram End Select End Function Protected _NameTrue As String = String.Empty - Friend ReadOnly Property NameTrue As String + Friend ReadOnly Property NameTrue(Optional ByVal Exact As Boolean = False) As String Get - Return _NameTrue.IfNullOrEmpty(Name) + Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name)) End Get End Property Private UserNameRequested As Boolean = False @@ -178,6 +178,8 @@ Namespace API.Instagram GetTaggedData_VideoPic = .GetTagged_VideoPic PutImageVideoFolder = .PutImageVideoFolder + + _NameTrue = .UserName End With End If End Sub @@ -631,7 +633,7 @@ Namespace API.Instagram 'Check environment If Not IsSavedPosts Then If ID.IsEmptyString Then GetUserData() - If ID.IsEmptyString Then Throw New Plugin.ExitException("can't get user ID") + If ID.IsEmptyString Then UserExists = False : _ForceSaveUserInfoOnException = True : Throw New Plugin.ExitException("can't get user ID") If _UseGQL And Cursor.IsEmptyString And Not Section = Sections.SavedPosts Then If Not ValidateBaseTokens() Then GetPageTokens() If Not ValidateBaseTokens(TokensErrData) Then ValidateBaseTokens_Error(TokensErrData) @@ -1171,6 +1173,7 @@ NextPageBlock: End Using End If Catch ex As Exception + UserExists = False If Not __idFound Then If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then Throw ex diff --git a/SCrawler/API/Mastodon/EditorExchangeOptions.vb b/SCrawler/API/Mastodon/EditorExchangeOptions.vb index a218601..c5fbf01 100644 --- a/SCrawler/API/Mastodon/EditorExchangeOptions.vb +++ b/SCrawler/API/Mastodon/EditorExchangeOptions.vb @@ -15,6 +15,7 @@ Namespace API.Mastodon Friend Overrides Property DownloadModelSearch As Boolean Friend Overrides Property DownloadModelForceApply As Boolean Friend Overrides Property DownloadModelLikes As Boolean + Friend Overrides Property UserName As String Friend Sub New(ByVal s As SiteSettings) MyBase.New(s) End Sub diff --git a/SCrawler/API/Reddit/Declarations.vb b/SCrawler/API/Reddit/Declarations.vb index be26dae..ad04dfd 100644 --- a/SCrawler/API/Reddit/Declarations.vb +++ b/SCrawler/API/Reddit/Declarations.vb @@ -21,6 +21,6 @@ Namespace API.Reddit Friend ReadOnly UrlBasePattern As RParams = RParams.DM("(?<=/)([^/]+?\.[\w]{3,4})(?=(\?|\Z))", 0) Friend ReadOnly VideoRegEx As RParams = RParams.DM("http.{0,1}://[^" & Chr(34) & "]+?mp4", 0) Private ReadOnly EUR_PROVIDER As New ANumbers(ANumbers.Cultures.EUR) - Friend ReadOnly UnixDate32ProviderReddit As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnix32(AConvert(Of Integer)(v, EUR_PROVIDER, v), n, e)) + Friend ReadOnly UnixDate32ProviderReddit As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnix32(AConvert(Of Double)(v, EUR_PROVIDER, v), n, e)) End Module End Namespace \ No newline at end of file diff --git a/SCrawler/API/Twitter/EditorExchangeOptions.vb b/SCrawler/API/Twitter/EditorExchangeOptions.vb index c6a9e1c..1109160 100644 --- a/SCrawler/API/Twitter/EditorExchangeOptions.vb +++ b/SCrawler/API/Twitter/EditorExchangeOptions.vb @@ -8,6 +8,7 @@ ' but WITHOUT ANY WARRANTY Imports SCrawler.Plugin.Attributes Imports DModels = SCrawler.API.Twitter.UserData.DownloadModels +Imports DN = SCrawler.API.Base.DeclaredNames Namespace API.Twitter Friend Class EditorExchangeOptions Private Const DefaultOffset As Integer = 100 @@ -46,6 +47,8 @@ Namespace API.Twitter Caption:="Force apply", ToolTip:="Force overrides the default parameters for the first download." & vbCr & "Applies to first download only.", LeftOffset:=DefaultOffset)> Friend Overridable Property DownloadModelForceApply As Boolean = False + + Friend Overridable Property UserName As String = String.Empty Private ReadOnly Property MySettings As Object Friend Sub New(ByVal s As SiteSettings) GifsDownload = s.GifsDownload.Value @@ -80,6 +83,7 @@ Namespace API.Twitter DownloadModelLikes = dm.Contains(DModels.Likes) End If End If + UserName = u.NameTrue(True) MySettings = u.HOST.Source End Sub End Class diff --git a/SCrawler/API/Twitter/UserData.vb b/SCrawler/API/Twitter/UserData.vb index a8987b5..e73ce52 100644 --- a/SCrawler/API/Twitter/UserData.vb +++ b/SCrawler/API/Twitter/UserData.vb @@ -31,9 +31,9 @@ Namespace API.Twitter #Region "Declarations" Private Const Label_Community As String = "Community" Private _NameTrue As String = String.Empty - Friend Property NameTrue As String + Friend Property NameTrue(Optional ByVal Exact As Boolean = False) As String Get - Return _NameTrue.IfNullOrEmpty(Name) + Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name)) End Get Set(ByVal NewName As String) _NameTrue = NewName @@ -98,6 +98,7 @@ Namespace API.Twitter If .DownloadModelProfile Then DownloadModel += DownloadModels.Profile If .DownloadModelSearch Then DownloadModel += DownloadModels.Search If .DownloadModelLikes Then DownloadModel += DownloadModels.Likes + _NameTrue = .UserName End With End If End Sub diff --git a/SCrawler/Content/Pictures/FindPic_16.png b/SCrawler/Content/Pictures/FindPic_16.png new file mode 100644 index 0000000..2bc6e48 Binary files /dev/null and b/SCrawler/Content/Pictures/FindPic_16.png differ diff --git a/SCrawler/Download/Feed/DownloadFeedForm.vb b/SCrawler/Download/Feed/DownloadFeedForm.vb index 334a65e..c1c4354 100644 --- a/SCrawler/Download/Feed/DownloadFeedForm.vb +++ b/SCrawler/Download/Feed/DownloadFeedForm.vb @@ -542,6 +542,7 @@ Namespace DownloadObjects End Try End Sub #End Region +#Region "Move/Copy" Private Sub BTT_COPY_MOVE_TO_Click(sender As Object, e As EventArgs) Handles BTT_COPY_TO.Click, BTT_MOVE_TO.Click MoveCopyFiles(True, sender, Nothing, Nothing) End Sub @@ -769,6 +770,7 @@ Namespace DownloadObjects Settings.Feeds.UpdateWhereDataReplaced() End Try End Function +#End Region #Region "Load fav, spec" Private Sub BTT_LOAD_FAV_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_FAV.Click FeedChangeMode(FeedModes.Special, {FeedSpecial.FavoriteName}) @@ -1312,32 +1314,36 @@ Namespace DownloadObjects End Try End Sub Private Sub RefillAfterDelete() - With MyRange - Dim indx% = .CurrentIndex - Dim indxChanged As Boolean = False - .HandlersSuspended = True - .Update() - If .Count > 0 Then - If indx.ValueBetween(0, .Count - 1) Then - .CurrentIndex = indx - ElseIf (indx - 1).ValueBetween(0, .Count - 1) Then - .CurrentIndex = indx - 1 - indxChanged = True - Else - .CurrentIndex = .Count - 1 - indxChanged = Not indx = .CurrentIndex + Try + With MyRange + Dim indx% = .CurrentIndex + Dim indxChanged As Boolean = False + .HandlersSuspended = True + .Update() + If .Count > 0 Then + If indx.ValueBetween(0, .Count - 1) Then + .CurrentIndex = indx + ElseIf (indx - 1).ValueBetween(0, .Count - 1) Then + .CurrentIndex = indx - 1 + indxChanged = True + Else + .CurrentIndex = .Count - 1 + indxChanged = Not indx = .CurrentIndex + End If + .UpdateControls() + .HandlersSuspended = False + If Not indxChanged Then LatestScrollValueDisabled = True + DirectCast(MyRange.Switcher, RangeSwitcher(Of UserMediaD)).PerformIndexChanged() + If Not indxChanged Then + LatestScrollValueDisabled = False + SetScrollValue(True) + End If End If - .UpdateControls() .HandlersSuspended = False - If Not indxChanged Then LatestScrollValueDisabled = True - DirectCast(MyRange.Switcher, RangeSwitcher(Of UserMediaD)).PerformIndexChanged() - If Not indxChanged Then - LatestScrollValueDisabled = False - SetScrollValue(True) - End If - End If - .HandlersSuspended = False - End With + End With + Catch ex As Exception + ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadFeedForm.RefillAfterDelete]") + End Try End Sub #End Region #Region "Range" diff --git a/SCrawler/MainFrame.Designer.vb b/SCrawler/MainFrame.Designer.vb index 7340aaa..fbe31e9 100644 --- a/SCrawler/MainFrame.Designer.vb +++ b/SCrawler/MainFrame.Designer.vb @@ -40,12 +40,14 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Dim MENU_DOWN_ALL_SEP_3 As System.Windows.Forms.ToolStripSeparator Dim MENU_DOWN_ALL_SEP_4 As System.Windows.Forms.ToolStripSeparator Dim MENU_INFO As System.Windows.Forms.ToolStripDropDownButton + Dim MENU_INFO_SEP_1 As System.Windows.Forms.ToolStripSeparator Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MainFrame)) Me.MENU_INFO_SHOW_INFO = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_QUEUE = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_MISSING = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_INFO_SHOW_USER_METRICS = New System.Windows.Forms.ToolStripMenuItem() + Me.MENU_INFO_USER_SEARCH = New System.Windows.Forms.ToolStripMenuItem() Me.MENU_SETTINGS = New System.Windows.Forms.ToolStripDropDownButton() Me.BTT_SETTINGS = New System.Windows.Forms.ToolStripMenuItem() Me.Toolbar_TOP = New System.Windows.Forms.ToolStrip() @@ -140,6 +142,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form MENU_DOWN_ALL_SEP_3 = New System.Windows.Forms.ToolStripSeparator() MENU_DOWN_ALL_SEP_4 = New System.Windows.Forms.ToolStripSeparator() MENU_INFO = New System.Windows.Forms.ToolStripDropDownButton() + MENU_INFO_SEP_1 = New System.Windows.Forms.ToolStripSeparator() MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator() Me.Toolbar_TOP.SuspendLayout() Me.Toolbar_BOTTOM.SuspendLayout() @@ -235,7 +238,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form 'MENU_INFO ' MENU_INFO.AutoToolTip = False - MENU_INFO.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_INFO_SHOW_INFO, Me.MENU_INFO_SHOW_QUEUE, Me.MENU_INFO_SHOW_MISSING, Me.MENU_INFO_SHOW_USER_METRICS}) + MENU_INFO.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_INFO_SHOW_INFO, Me.MENU_INFO_SHOW_QUEUE, Me.MENU_INFO_SHOW_MISSING, MENU_INFO_SEP_1, Me.MENU_INFO_SHOW_USER_METRICS, Me.MENU_INFO_USER_SEARCH}) MENU_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32 MENU_INFO.ImageTransparentColor = System.Drawing.Color.Magenta MENU_INFO.Name = "MENU_INFO" @@ -268,6 +271,11 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Me.MENU_INFO_SHOW_MISSING.Text = "Missing posts" Me.MENU_INFO_SHOW_MISSING.ToolTipText = "Open the 'Missing' form (show information about missing posts)." ' + 'MENU_INFO_SEP_1 + ' + MENU_INFO_SEP_1.Name = "MENU_INFO_SEP_1" + MENU_INFO_SEP_1.Size = New System.Drawing.Size(209, 6) + ' 'MENU_INFO_SHOW_USER_METRICS ' Me.MENU_INFO_SHOW_USER_METRICS.AutoToolTip = True @@ -277,6 +285,13 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Me.MENU_INFO_SHOW_USER_METRICS.Text = "User metrics" Me.MENU_INFO_SHOW_USER_METRICS.ToolTipText = "Open the ""User metrics' form (show information about the user's metrics (such as " & "size, number of files, etc.))." + ' + 'MENU_INFO_USER_SEARCH + ' + Me.MENU_INFO_USER_SEARCH.Image = Global.SCrawler.My.Resources.Resources.FindPic_16 + Me.MENU_INFO_USER_SEARCH.Name = "MENU_INFO_USER_SEARCH" + Me.MENU_INFO_USER_SEARCH.Size = New System.Drawing.Size(212, 22) + Me.MENU_INFO_USER_SEARCH.Text = "Find user" ' 'MENU_VIEW_SEP_1 ' @@ -993,4 +1008,5 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form Private WithEvents BTT_VIEW_FILTER_SAVE As ToolStripMenuItem Private WithEvents BTT_VIEW_FILTER_LOAD As ToolStripMenuItem Private WithEvents BTT_VIEW_FILTER_SAVE_AS_GROUP As ToolStripMenuItem + Private WithEvents MENU_INFO_USER_SEARCH As ToolStripMenuItem End Class \ No newline at end of file diff --git a/SCrawler/MainFrame.resx b/SCrawler/MainFrame.resx index e814de1..fec7b8b 100644 --- a/SCrawler/MainFrame.resx +++ b/SCrawler/MainFrame.resx @@ -171,6 +171,9 @@ False + + False + False diff --git a/SCrawler/MainFrame.vb b/SCrawler/MainFrame.vb index a01c52e..9d4d29c 100644 --- a/SCrawler/MainFrame.vb +++ b/SCrawler/MainFrame.vb @@ -479,6 +479,9 @@ CloseResume: Private Sub MENU_INFO_SHOW_USER_METRICS_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_USER_METRICS.Click MyUserMetrics.FormShow(EDP.LogMessageValue) End Sub + Private Sub MENU_INFO_USER_SEARCH_Click(sender As Object, e As EventArgs) Handles MENU_INFO_USER_SEARCH.Click + MySearch.FormShow() + End Sub #End Region Friend Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click If MyFeed Is Nothing Then diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb index f20c41e..138c96b 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/My Project/Resources.Designer.vb b/SCrawler/My Project/Resources.Designer.vb index 5eeb9d7..23ea2b9 100644 --- a/SCrawler/My Project/Resources.Designer.vb +++ b/SCrawler/My Project/Resources.Designer.vb @@ -150,6 +150,16 @@ Namespace My.Resources End Get End Property + ''' + ''' Looks up a localized resource of type System.Drawing.Bitmap. + ''' + Friend ReadOnly Property FindPic_16() As System.Drawing.Bitmap + Get + Dim obj As Object = ResourceManager.GetObject("FindPic_16", resourceCulture) + Return CType(obj,System.Drawing.Bitmap) + End Get + End Property + ''' ''' Looks up a localized resource of type System.Drawing.Bitmap. ''' diff --git a/SCrawler/My Project/Resources.resx b/SCrawler/My Project/Resources.resx index 9f63ed8..3acf909 100644 --- a/SCrawler/My Project/Resources.resx +++ b/SCrawler/My Project/Resources.resx @@ -223,4 +223,7 @@ ..\Content\Pictures\CutPic_48.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Content\Pictures\FindPic_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb b/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb index 0a5dda7..1093da7 100644 --- a/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb +++ b/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb @@ -335,7 +335,7 @@ Namespace Plugin.Hosts ByVal ColNameOld As String, ByVal ColNameNew As String) As Boolean Dim p As PauseModes = NoPauseMode Try - If UpdateHostPath_CheckDownloader() Then Return False + If Not UpdateHostPath_CheckDownloader() Then Return False If Not AEquals(Of String)(PathOld.PathWithSeparator, PathNew.PathWithSeparator) Or Not AEquals(Of String)(ColNameOld, ColNameNew) Then p = Settings.Automation.Pause Settings.Automation.Pause = PauseModes.Unlimited @@ -365,7 +365,7 @@ Namespace Plugin.Hosts Optional ByVal ForceCollections As Boolean = False) As Boolean Dim p As PauseModes = NoPauseMode Try - If UpdateHostPath_CheckDownloader() Then Return False + If Not UpdateHostPath_CheckDownloader() Then Return False If Not PathNew.IsEmptyString And Settings.UsersList.Count > 0 Then Dim hp As SFile = Host.Path(False, True) Dim diffPaths As Boolean = (Abs And hp.PathWithSeparator = PathOld.PathWithSeparator) Or diff --git a/SCrawler/SCrawler.vbproj b/SCrawler/SCrawler.vbproj index cda0848..8080a96 100644 --- a/SCrawler/SCrawler.vbproj +++ b/SCrawler/SCrawler.vbproj @@ -798,6 +798,7 @@ +