From aef4ce1c8f15c70e3b1352de33be1c3b9a6f7eab Mon Sep 17 00:00:00 2001 From: Andy <88590076+AAndyProgram@users.noreply.github.com> Date: Mon, 10 Jun 2024 08:40:40 +0300 Subject: [PATCH] 2024.6.10.0 YT YouTubeSettings: add 'VideoPlaylist_AddExtractedMP3' property MediaItem: improve visualization of height and bitrate YouTubeMediaContainerBase: fix bugs on default post-processing formats; add 'HeightBase' and 'BitrateBase' properties; add extracted MP3 to playlist VideoListForm: add 'UpdateLogButton' handlers SCrawler Feed: add settings to show/hide site name and file type from media title; add move/copy files of a loaded feed/session to another location; add the ability to reset current session DownloadFeedForm: when moving saved posts files without replacing the profile, some data is lost FeedVideo: add double-click handler to open video in external player API.Instagram: update settings --- Changelog.md | 13 +++ ProgramScreenshots/SettingsGlobalFeed.png | Bin 20890 -> 22445 bytes SCrawler.YouTube/Base/YouTubeSettings.vb | 3 + SCrawler.YouTube/Downloader/MediaItem.vb | 15 +++- SCrawler.YouTube/Downloader/VideoListForm.vb | 26 +++++- SCrawler.YouTube/My Project/AssemblyInfo.vb | 4 +- .../Objects/YouTubeMediaContainerBase.vb | 67 ++++++++++----- .../My Project/AssemblyInfo.vb | 4 +- SCrawler/API/Instagram/SiteSettings.vb | 9 +- SCrawler/API/OnlyFans/SiteSettings.vb | 2 +- SCrawler/API/OnlyFans/UserData.vb | 2 +- .../Feed/DownloadFeedForm.Designer.vb | 58 +++++++++++-- SCrawler/Download/Feed/DownloadFeedForm.resx | 3 + SCrawler/Download/Feed/DownloadFeedForm.vb | 33 ++++++-- SCrawler/Download/Feed/FeedMedia.vb | 16 ++-- SCrawler/Download/Feed/FeedSpecial.vb | 7 +- SCrawler/Download/Feed/FeedVideo.vb | 4 + SCrawler/Download/TDownloader.vb | 9 +- .../Editors/GlobalSettingsForm.Designer.vb | 77 ++++++++++++------ SCrawler/Editors/GlobalSettingsForm.vb | 4 + SCrawler/MainMod.vb | 6 ++ SCrawler/My Project/AssemblyInfo.vb | 4 +- SCrawler/SettingsCLS.vb | 4 + 23 files changed, 282 insertions(+), 88 deletions(-) diff --git a/Changelog.md b/Changelog.md index ba1b3dc..828d6d5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,16 @@ +# 2024.6.10.0 + +*2024-06-10* + +- Added + - YouTube (standalone app): add option to add extracted MP3 to playlist (`Settings` - `Defaults Video` - `Add extracted MP3 to playlist`) + - Feed + - settings to show/hide site name and file type from media title + - ability to move/copy files of a loaded feed/session to another location + - ability to reset current session +- Fixed + - Minor bugs + # 2024.6.6.0 *2024-06-06* diff --git a/ProgramScreenshots/SettingsGlobalFeed.png b/ProgramScreenshots/SettingsGlobalFeed.png index db6b5b9f440d248fd32369e0d36342f4bb55bf7c..9859e9a56f388958cf00b6492b4ac9bb37cfdcf4 100644 GIT binary patch literal 22445 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 literal 20890 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 Public ReadOnly Property DefaultVideoHighlightFPS_L As XMLValue(Of Integer) + + Public ReadOnly Property VideoPlaylist_AddExtractedMP3 As XMLValue(Of Boolean) #End Region #Region "Defaults Audio" 0 Then - LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{ .Height}p" + If h > 0 Then + LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{h}p" Else LBL_INFO.Text = .File.Extension.StringToUpper End If Else - If .Bitrate > 0 Then - LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{ .Bitrate}k" + If b > 0 Then + LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{b}k" Else LBL_INFO.Text = .File.Extension.StringToUpper End If diff --git a/SCrawler.YouTube/Downloader/VideoListForm.vb b/SCrawler.YouTube/Downloader/VideoListForm.vb index 2fc0226..e55ed7b 100644 --- a/SCrawler.YouTube/Downloader/VideoListForm.vb +++ b/SCrawler.YouTube/Downloader/VideoListForm.vb @@ -57,6 +57,12 @@ Namespace DownloadObjects.STDownloader End If MyNotificator = New YTNotificator(Me) MyDownloaderSettings = MyYouTubeSettings + ProgramLogInitialize() + With ProgramLog + AddHandler .TextAdded, AddressOf ProgramLog_TextAdded + AddHandler .TextCleared, AddressOf ProgramLog_TextCleared + End With + UpdateLogButton() End If With MyView : .Import() : .SetFormSize() : End With @@ -157,7 +163,7 @@ Namespace DownloadObjects.STDownloader If PerformClick Then cnt.PerformClick() If Not DisableDownload And MyDownloaderSettings.DownloadAutomatically Then AddToDownload(cnt, True) End With - End Sub, EDP.None) + End Sub, EDP.SendToLog) End Sub #Region "Controls rendering" Private Overloads Sub OffsetControls() @@ -449,12 +455,26 @@ Namespace DownloadObjects.STDownloader End Try End Sub #End Region +#Region "LOG" Private Sub BTT_LOG_Click(sender As Object, e As EventArgs) Handles BTT_LOG.Click MyMainLOG_ShowForm(DesignXML,,,, AddressOf UpdateLogButton) End Sub - Friend Sub UpdateLogButton() - If AppMode Then MyMainLOG_UpdateLogButton(BTT_LOG, TOOLBAR_TOP) + Private Sub UpdateLogButton() + If AppMode Then + Try : MyMainLOG_UpdateLogButton(BTT_LOG, TOOLBAR_TOP) : Catch : End Try + End If End Sub + Private _LogUpdateButtonSuspended As Boolean = False + Private Sub ProgramLog_TextAdded(ByVal Sender As Object, ByVal e As EventArgs) + If Not _LogUpdateButtonSuspended Then + _LogUpdateButtonSuspended = True + Try : ControlInvokeFast(TOOLBAR_TOP, BTT_LOG, AddressOf UpdateLogButton, EDP.None) : Catch : End Try + End If + End Sub + Private Sub ProgramLog_TextCleared(ByVal Sender As Object, ByVal e As EventArgs) + _LogUpdateButtonSuspended = False + End Sub +#End Region Private Sub BTT_BUG_REPORT_Click(sender As Object, e As EventArgs) Handles BTT_BUG_REPORT.Click Try With MyYouTubeSettings diff --git a/SCrawler.YouTube/My Project/AssemblyInfo.vb b/SCrawler.YouTube/My Project/AssemblyInfo.vb index f936c5c..de27cb4 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 e406d8d..bc8d2c5 100644 --- a/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb +++ b/SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb @@ -267,12 +267,11 @@ Namespace API.YouTube.Objects Friend ReadOnly Property PostProcessing_OutputAudioFormats As List(Of String) Friend Sub PostProcessing_OutputAudioFormats_Reset() - PostProcessing_OutputAudioFormats.Clear() - PostProcessing_OutputAudioFormats.ListAddList(MyYouTubeSettings.DefaultAudioCodecAddit) - If PostProcessing_OutputAudioFormats.Count > 0 Then - PostProcessing_OutputAudioFormats.Sort() - PostProcessing_OutputAudioFormats.RemoveAll(Function(s) s = -1) - End If + With PostProcessing_OutputAudioFormats + .Clear() + .ListAddList(MyYouTubeSettings.DefaultAudioCodecAddit) + If .Count > 0 Then .Sort() + End With End Sub Protected _OutputAudioBitrate As Integer = -1 Friend Property OutputAudioBitrate As Integer @@ -322,21 +321,19 @@ Namespace API.YouTube.Objects Friend ReadOnly Property PostProcessing_OutputSubtitlesFormats As List(Of String) Friend Sub PostProcessing_OutputSubtitlesFormats_Reset() - PostProcessing_OutputSubtitlesFormats.Clear() - PostProcessing_OutputSubtitlesFormats.ListAddList(MyYouTubeSettings.DefaultSubtitlesFormatAddit) - If PostProcessing_OutputSubtitlesFormats.Count > 0 Then - PostProcessing_OutputSubtitlesFormats.Sort() - PostProcessing_OutputSubtitlesFormats.RemoveAll(Function(s) s = -1) - End If + With PostProcessing_OutputSubtitlesFormats + .Clear() + .ListAddList(MyYouTubeSettings.DefaultSubtitlesFormatAddit) + If .Count > 0 Then .Sort() + End With End Sub Friend Sub SubtitlesSelectedIndexesReset() - SubtitlesSelectedIndexes.Clear() - Dim subs As List(Of Subtitles) = Subtitles - SubtitlesSelectedIndexes.ListAddList(MyYouTubeSettings.DefaultSubtitles.Select(Function(s) subs.FindIndex(Function(ss) ss.ID = s))) - If SubtitlesSelectedIndexes.Count > 0 Then - SubtitlesSelectedIndexes.Sort() - SubtitlesSelectedIndexes.RemoveAll(Function(s) s = -1) - End If + With SubtitlesSelectedIndexes + .Clear() + Dim subs As List(Of Subtitles) = Subtitles + .ListAddList(MyYouTubeSettings.DefaultSubtitles.Select(Function(s) subs.FindIndex(Function(ss) ss.ID = s))) + If .Count > 0 Then .Sort() : .RemoveAll(Function(s) s = -1) + End With End Sub Private Sub SetElementsSubtitles(ByVal Source As YouTubeMediaContainerBase) If Not Source Is Nothing And HasElements Then @@ -442,6 +439,19 @@ Namespace API.YouTube.Objects End Get End Property Public Property Height As Integer Implements IYouTubeMediaContainer.Height + Friend ReadOnly Property HeightBase As Integer + Get + If Height > 0 Then + Return Height + ElseIf SelectedVideoIndex.ValueBetween(0, MediaObjects.Count - 1) Then + Return SelectedVideo.Height + ElseIf SelectedAudioIndex.ValueBetween(0, MediaObjects.Count - 1) Then + Return SelectedAudio.Height + Else + Return 0 + End If + End Get + End Property Protected _Bitrate As Integer = 0 Public Overridable Property Bitrate As Integer Implements IYouTubeMediaContainer.Bitrate Get @@ -459,6 +469,20 @@ Namespace API.YouTube.Objects Me._Bitrate = _Bitrate End Set End Property + Friend ReadOnly Property BitrateBase As Integer + Get + If Bitrate > 0 Then + Return Bitrate + ElseIf OutputAudioBitrate > 0 Then + Return OutputAudioBitrate + ElseIf HasElements Then + Try : Return Elements.Average(Function(e) DirectCast(e, YouTubeMediaContainerBase).BitrateBase) : Catch : End Try + ElseIf SelectedAudioIndex.ValueBetween(0, MediaObjects.Count - 1) Then + Return SelectedAudio.Bitrate + End If + Return 0 + End Get + End Property Public Property DateCreated As Date = Now Implements IYouTubeMediaContainer.DateCreated Public Property DateAdded As Date Implements IYouTubeMediaContainer.DateAdded Private Property IUserMedia_PostDate As Date? Implements IUserMedia.PostDate @@ -975,7 +999,7 @@ Namespace API.YouTube.Objects .Visible = True .Value = 0 .Maximum = DownloadGetElemCountSingle() - .Information = $"Download {ObjectType}" + .Information = "Downloading" End With End If @@ -1120,7 +1144,7 @@ Namespace API.YouTube.Objects .Value = 0 .Maximum = 100 .Provider = ProgressProvider - .Information = $"Download {MediaType}" + .Information = "Downloading" End With End If .MainProcessName = MyYouTubeSettings.YTDLP.Name '"yt-dlp" @@ -1305,6 +1329,7 @@ Namespace API.YouTube.Objects If format = mp3 And Not mp3ThumbEmbedded And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _ embedThumbTo.Invoke(f) : mp3ThumbEmbedded = True If Not M3U8_PlaylistFiles.ListExists AndAlso f.Exists Then M3U8_Append(f) + If format = mp3 AndAlso f.Exists AndAlso MyYouTubeSettings.VideoPlaylist_AddExtractedMP3.Value Then M3U8_Append(f) End If Next End If diff --git a/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb b/SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb index 867e77c..8779f05 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/Instagram/SiteSettings.vb b/SCrawler/API/Instagram/SiteSettings.vb index 812c49d..01ecf3e 100644 --- a/SCrawler/API/Instagram/SiteSettings.vb +++ b/SCrawler/API/Instagram/SiteSettings.vb @@ -446,10 +446,11 @@ Namespace API.Instagram Friend Overrides Sub EndInit() Try : MyLastRequests.Add(LastDownloadDate.Value, LastRequestsCount.Value) : Catch : End Try If Not CBool(HH_IG_WWW_CLAIM_USE.Value) Then Responser.Headers.Remove(Header_IG_WWW_CLAIM) - If CInt(SettingsVersion.Value) < 1 Then - SettingsVersion.Value = 1 - HH_IG_WWW_CLAIM_UPDATE_INTERVAL.Value = 59 - HH_IG_WWW_CLAIM_USE_DEFAULT_ALGO.Value = 0 + If CInt(SettingsVersion.Value) < 2 Then + SettingsVersion.Value = 2 + HH_IG_WWW_CLAIM_UPDATE_INTERVAL.Value = 120 + HH_IG_WWW_CLAIM_USE_DEFAULT_ALGO.Value = 1 + HH_IG_WWW_CLAIM_RESET_EACH_TARGET.Value = 0 End If MyBase.EndInit() End Sub diff --git a/SCrawler/API/OnlyFans/SiteSettings.vb b/SCrawler/API/OnlyFans/SiteSettings.vb index a3e49fe..0698f86 100644 --- a/SCrawler/API/OnlyFans/SiteSettings.vb +++ b/SCrawler/API/OnlyFans/SiteSettings.vb @@ -228,7 +228,7 @@ Namespace API.OnlyFans Friend Overrides Sub Update() If _SiteEditorFormOpened Then If Not __UseOldAuthRules = CBool(UseOldAuthRules.Value) Or Not AEquals(Of String)(__DynamicRules, DynamicRules.Value) Then _ - LastDateUpdated = LastDateUpdated.AddYears(-1) + LastDateUpdated = Now.AddYears(-1) Responser.Cookies.Changed = False End If MyBase.Update() diff --git a/SCrawler/API/OnlyFans/UserData.vb b/SCrawler/API/OnlyFans/UserData.vb index 3dff87a..60e7176 100644 --- a/SCrawler/API/OnlyFans/UserData.vb +++ b/SCrawler/API/OnlyFans/UserData.vb @@ -619,7 +619,7 @@ Namespace API.OnlyFans Dim checkFormat As Func(Of EContainer, Boolean) = Function(jj) Not jj.Value("format").IsEmptyString OrElse (Not jj.Value("prefix").IsEmptyString And Not jj.Value("suffix").IsEmptyString) OrElse - (Not jj.Value("start").IsEmptyString And Not jj.Value("start").IsEmptyString) + (Not jj.Value("start").IsEmptyString And Not jj.Value("end").IsEmptyString) If Not r.IsEmptyString Then Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue) If j.ListExists Then diff --git a/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb b/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb index 63af54e..80a407b 100644 --- a/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb +++ b/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb @@ -35,6 +35,7 @@ Namespace DownloadObjects Dim MENU_LOAD_SEP_7 As System.Windows.Forms.ToolStripSeparator Dim MENU_LOAD_SEP_0 As System.Windows.Forms.ToolStripSeparator Dim MENU_LOAD_SEP_8 As System.Windows.Forms.ToolStripSeparator + Dim MENU_LOAD_SEP_9 As System.Windows.Forms.ToolStripSeparator Me.OPT_DEFAULT = New System.Windows.Forms.ToolStripMenuItem() Me.OPT_SUBSCRIPTIONS = New System.Windows.Forms.ToolStripMenuItem() Me.ToolbarTOP = New System.Windows.Forms.ToolStrip() @@ -57,6 +58,7 @@ Namespace DownloadObjects Me.BTT_FEED_DELETE_SPEC = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_FEED_DELETE_DAILY_LIST = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_FEED_DELETE_DAILY_DATE = New System.Windows.Forms.ToolStripMenuItem() + Me.BTT_CURR_SESSION_SET = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_MERGE_SESSIONS = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_CLEAR_DAILY = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_MERGE_FEEDS = New System.Windows.Forms.ToolStripMenuItem() @@ -70,7 +72,9 @@ Namespace DownloadObjects Me.BTT_DOWN_SELECTED = New System.Windows.Forms.ToolStripMenuItem() Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton() Me.TP_DATA = New System.Windows.Forms.TableLayoutPanel() - Me.BTT_CURR_SESSION_SET = New System.Windows.Forms.ToolStripMenuItem() + Me.BTT_COPY_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem() + Me.BTT_MOVE_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem() + Me.BTT_RESET_DAILY = New System.Windows.Forms.ToolStripMenuItem() SEP_1 = New System.Windows.Forms.ToolStripSeparator() SEP_2 = New System.Windows.Forms.ToolStripSeparator() MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton() @@ -83,6 +87,7 @@ Namespace DownloadObjects MENU_LOAD_SEP_7 = New System.Windows.Forms.ToolStripSeparator() MENU_LOAD_SEP_0 = New System.Windows.Forms.ToolStripSeparator() MENU_LOAD_SEP_8 = New System.Windows.Forms.ToolStripSeparator() + MENU_LOAD_SEP_9 = New System.Windows.Forms.ToolStripSeparator() Me.ToolbarTOP.SuspendLayout() Me.SuspendLayout() ' @@ -176,7 +181,7 @@ Namespace DownloadObjects ' Me.MENU_LOAD_SESSION.AutoToolTip = False Me.MENU_LOAD_SESSION.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image - Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_0, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, MENU_LOAD_SEP_1, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_2, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_4, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE, MENU_LOAD_SEP_5, Me.BTT_CURR_SESSION_SET, Me.BTT_MERGE_SESSIONS, Me.BTT_CLEAR_DAILY, MENU_LOAD_SEP_6, Me.BTT_MERGE_FEEDS, MENU_LOAD_SEP_7, Me.BTT_CHECK_ALL, Me.BTT_CHECK_NONE, MENU_LOAD_SEP_8, Me.BTT_VIEW_SAVE, Me.BTT_VIEW_LOAD}) + Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_0, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, MENU_LOAD_SEP_1, Me.BTT_COPY_SPEC_TO, Me.BTT_MOVE_SPEC_TO, MENU_LOAD_SEP_2, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_4, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_5, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE, MENU_LOAD_SEP_6, Me.BTT_CURR_SESSION_SET, Me.BTT_MERGE_SESSIONS, Me.BTT_CLEAR_DAILY, Me.BTT_RESET_DAILY, MENU_LOAD_SEP_7, Me.BTT_MERGE_FEEDS, MENU_LOAD_SEP_8, Me.BTT_CHECK_ALL, Me.BTT_CHECK_NONE, MENU_LOAD_SEP_9, Me.BTT_VIEW_SAVE, Me.BTT_VIEW_LOAD}) Me.MENU_LOAD_SESSION.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24 Me.MENU_LOAD_SESSION.ImageTransparentColor = System.Drawing.Color.Magenta Me.MENU_LOAD_SESSION.Name = "MENU_LOAD_SESSION" @@ -309,6 +314,15 @@ Namespace DownloadObjects Me.BTT_FEED_DELETE_DAILY_DATE.Size = New System.Drawing.Size(352, 22) Me.BTT_FEED_DELETE_DAILY_DATE.Text = "Delete daily feed (by date)" ' + 'BTT_CURR_SESSION_SET + ' + Me.BTT_CURR_SESSION_SET.AutoToolTip = True + Me.BTT_CURR_SESSION_SET.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24 + Me.BTT_CURR_SESSION_SET.Name = "BTT_CURR_SESSION_SET" + Me.BTT_CURR_SESSION_SET.Size = New System.Drawing.Size(352, 22) + Me.BTT_CURR_SESSION_SET.Text = "Set current session..." + Me.BTT_CURR_SESSION_SET.ToolTipText = "Select one of the download sessions and set it as the current session" + ' 'BTT_MERGE_SESSIONS ' Me.BTT_MERGE_SESSIONS.AutoToolTip = True @@ -429,14 +443,37 @@ Namespace DownloadObjects Me.TP_DATA.Size = New System.Drawing.Size(484, 436) Me.TP_DATA.TabIndex = 1 ' - 'BTT_CURR_SESSION_SET + 'MENU_LOAD_SEP_9 ' - Me.BTT_CURR_SESSION_SET.AutoToolTip = True - Me.BTT_CURR_SESSION_SET.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24 - Me.BTT_CURR_SESSION_SET.Name = "BTT_CURR_SESSION_SET" - Me.BTT_CURR_SESSION_SET.Size = New System.Drawing.Size(352, 22) - Me.BTT_CURR_SESSION_SET.Text = "Set current session..." - Me.BTT_CURR_SESSION_SET.ToolTipText = "Select one of the download sessions and set it as the current session" + MENU_LOAD_SEP_9.Name = "MENU_LOAD_SEP_9" + MENU_LOAD_SEP_9.Size = New System.Drawing.Size(349, 6) + ' + 'BTT_COPY_SPEC_TO + ' + Me.BTT_COPY_SPEC_TO.AutoToolTip = True + Me.BTT_COPY_SPEC_TO.Image = Global.SCrawler.My.Resources.Resources.PastePic_32 + Me.BTT_COPY_SPEC_TO.Name = "BTT_COPY_SPEC_TO" + Me.BTT_COPY_SPEC_TO.Size = New System.Drawing.Size(352, 22) + Me.BTT_COPY_SPEC_TO.Text = "Copy feed/session files to..." + Me.BTT_COPY_SPEC_TO.ToolTipText = "Copy all the files of the loaded feed/session to..." + ' + 'BTT_MOVE_SPEC_TO + ' + Me.BTT_MOVE_SPEC_TO.AutoToolTip = True + Me.BTT_MOVE_SPEC_TO.Image = Global.SCrawler.My.Resources.Resources.CutPic_48 + Me.BTT_MOVE_SPEC_TO.Name = "BTT_MOVE_SPEC_TO" + Me.BTT_MOVE_SPEC_TO.Size = New System.Drawing.Size(352, 22) + Me.BTT_MOVE_SPEC_TO.Text = "Move feed/session files to..." + Me.BTT_MOVE_SPEC_TO.ToolTipText = "Move all the files of the loaded feed/session to..." + ' + 'BTT_RESET_DAILY + ' + Me.BTT_RESET_DAILY.AutoToolTip = True + Me.BTT_RESET_DAILY.Image = Global.SCrawler.My.Resources.Resources.RefreshPic_24 + Me.BTT_RESET_DAILY.Name = "BTT_RESET_DAILY" + Me.BTT_RESET_DAILY.Size = New System.Drawing.Size(352, 22) + Me.BTT_RESET_DAILY.Text = "Reset current session" + Me.BTT_RESET_DAILY.ToolTipText = "A new file will be created for the current session" ' 'DownloadFeedForm ' @@ -494,5 +531,8 @@ Namespace DownloadObjects Private WithEvents BTT_VIEW_SAVE As ToolStripMenuItem Private WithEvents BTT_VIEW_LOAD As ToolStripMenuItem Private WithEvents BTT_CURR_SESSION_SET As ToolStripMenuItem + Private WithEvents BTT_COPY_SPEC_TO As ToolStripMenuItem + Private WithEvents BTT_MOVE_SPEC_TO As ToolStripMenuItem + Private WithEvents BTT_RESET_DAILY As ToolStripMenuItem End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Download/Feed/DownloadFeedForm.resx b/SCrawler/Download/Feed/DownloadFeedForm.resx index 5d446a2..042d779 100644 --- a/SCrawler/Download/Feed/DownloadFeedForm.resx +++ b/SCrawler/Download/Feed/DownloadFeedForm.resx @@ -165,4 +165,7 @@ 17, 17 + + False + \ No newline at end of file diff --git a/SCrawler/Download/Feed/DownloadFeedForm.vb b/SCrawler/Download/Feed/DownloadFeedForm.vb index 7c0fff1..5f2557c 100644 --- a/SCrawler/Download/Feed/DownloadFeedForm.vb +++ b/SCrawler/Download/Feed/DownloadFeedForm.vb @@ -540,14 +540,19 @@ Namespace DownloadObjects 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 - Private Function MoveCopyFiles(ByVal IsInternal As Boolean, ByVal Sender As Object, ByVal MCTOptions As FeedMoveCopyTo, ByVal FeedMediaData As FeedMedia) As Boolean + Private Sub BTT_COPY_MOVE_SPEC_TO_Click(sender As Object, e As EventArgs) Handles BTT_COPY_SPEC_TO.Click, BTT_MOVE_SPEC_TO.Click + MoveCopyFiles(True, sender, Nothing, Nothing, False) + End Sub + Private Function MoveCopyFiles(ByVal IsInternal As Boolean, ByVal Sender As Object, ByVal MCTOptions As FeedMoveCopyTo, + ByVal FeedMediaData As FeedMedia, Optional ByVal GetChecked As Boolean = True) As Boolean Const MsgTitle$ = "Copy/Move checked files" Try - Dim isCopy As Boolean = Not Sender Is Nothing AndAlso Sender Is BTT_COPY_TO + Dim isCopy As Boolean = Not Sender Is Nothing AndAlso (Sender Is BTT_COPY_TO OrElse Sender Is BTT_COPY_SPEC_TO) Dim moveOptions As FeedMoveCopyTo = Nothing Dim ff As SFile = Nothing, df As SFile Dim data As IEnumerable(Of UserMediaD) = Nothing Dim dd As UserMediaD + Dim __user As UserInfo Dim data_files As IEnumerable(Of SFile) = Nothing Dim new_files As New List(Of SFile) Dim mm As UserMediaD @@ -566,7 +571,12 @@ Namespace DownloadObjects Dim result As Boolean = False If FeedMediaData Is Nothing Then - data = GetCheckedMedia() + If GetChecked Then + data = GetCheckedMedia() + ElseIf DataList.Count > 0 Then + data = DataList.Where(Function(__dd) Not If(__dd.User?.IsSubscription, __dd.UserInfo.IsSubscription) AndAlso __dd.Data.File.Exists) + End If + With data If .ListExists Then data_files = .Select(Function(m) m.Data.File) End With @@ -587,7 +597,6 @@ Namespace DownloadObjects With moveOptions If Not .Destination.IsEmptyString And .ReplaceUserProfile And .ReplaceUserProfile_CreateIfNull And .ReplaceUserProfile_Profile Is Nothing Then Dim existingPathInstances As IEnumerable(Of String) = Nothing - Dim __user As UserInfo Dim __host As Plugin.Hosts.SettingsHost = Settings(API.PathPlugin.PluginKey).Default Dim __userName$ = .Destination.Segments.LastOrDefault If Settings.UsersList.Count > 0 Then _ @@ -659,9 +668,11 @@ Namespace DownloadObjects indx = Downloader.Files.FindIndex(finder) If indx >= 0 Then mm = Downloader.Files(indx) + __user = mm.UserInfo mm_data = mm.Data mm_data.File = df - mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) + mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) With {.IsSavedPosts = mm.IsSavedPosts} + If moveOptions.ReplaceUserProfile_Profile Is Nothing And mm.IsSavedPosts Then mm.UserInfo = __user Downloader.Files(indx) = mm downloaderFilesUpdated = True End If @@ -687,9 +698,11 @@ Namespace DownloadObjects indx = sessionData.FindIndex(finder) If indx >= 0 Then mm = sessionData(indx) + __user = mm.UserInfo mm_data = mm.Data mm_data.File = df - mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) + mm = New UserMediaD(mm_data, If(moveOptions.ReplaceUserProfile_Profile, mm.User), mm.Session, mm.Date) With {.IsSavedPosts = mm.IsSavedPosts} + If moveOptions.ReplaceUserProfile_Profile Is Nothing And mm.IsSavedPosts Then mm.UserInfo = __user sessionData(indx) = mm sesFilesReplaced = True If DataList.Count > 0 Then @@ -989,6 +1002,14 @@ Namespace DownloadObjects RefillList() End If End Sub + Private Sub BTT_RESET_DAILY_Click(sender As Object, e As EventArgs) Handles BTT_RESET_DAILY.Click + If MsgBoxE({"Are you sure you want to reset the current session?" & vbCr & + "A new file will be created for the current session", "Reset current session"}, vbExclamation,,, {"Process", "Cancel"}) = 0 Then + Downloader.ResetSession() + FeedChangeMode(FeedModes.Current) + RefillList(True, False) + End If + End Sub #End Region #Region "Merge feeds" Private Sub BTT_MERGE_FEEDS_Click(sender As Object, e As EventArgs) Handles BTT_MERGE_FEEDS.Click diff --git a/SCrawler/Download/Feed/FeedMedia.vb b/SCrawler/Download/Feed/FeedMedia.vb index 466a169..2eedd5c 100644 --- a/SCrawler/Download/Feed/FeedMedia.vb +++ b/SCrawler/Download/Feed/FeedMedia.vb @@ -221,8 +221,8 @@ Namespace DownloadObjects Information = $"Type: {Media.Data.Type}" Information.StringAppendLine($"File: {File.File}") Information.StringAppendLine($"Address: {File}") - Information.StringAppendLine($"Downloaded: {Media.Date.ToStringDate(ADateTime.Formats.BaseDateTime)}") - If Media.Data.Post.Date.HasValue Then Information.StringAppendLine($"Posted: {Media.Data.Post.Date.Value.ToStringDate(ADateTime.Formats.BaseDateTime)}") + Information.StringAppendLine($"Downloaded: {Media.Date.ToStringDateDef}") + If Media.Data.Post.Date.HasValue Then Information.StringAppendLine($"Post date: {Media.Data.Post.Date.Value.ToStringDateDef}") Dim infoType As UserMedia.Types = If(IsSubscription, UserMedia.Types.Picture, Media.Data.Type) Dim h% Dim s As Size @@ -267,23 +267,27 @@ Namespace DownloadObjects BTT_CONTEXT_OPEN_MEDIA.Text &= " video" BTT_CONTEXT_DELETE.Text &= " video" h = VideoHeight + AddHandler MyVideo.DoubleClick, AddressOf MyPicture_DoubleClick Case Else : Throw New ArgumentNullException With {.HelpLink = 1} End Select - Dim info$ = $"[{infoType}] - " + Dim info$ = If(Settings.FeedAddTypeToCaption.Value And Not IsSubscription, $"[{infoType}] - ", String.Empty) If Not Media.User Is Nothing Then With Media.User + Dim otherName$ = If(Media.IsSavedPosts, "Saved", Media.UserInfo.Name) + Dim site$ = If(Settings.FeedAddSiteToCaption.Value, $"{ .Site} - ", String.Empty) + UserKey = .Key Information &= vbNewLine.StringDup(2) If .IncludedInCollection Then Information.StringAppendLine($"User collection: { .CollectionName}") Information.StringAppendLine($"User site: { .Site}") - Information.StringAppendLine($"User name: {IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)}") + Information.StringAppendLine($"User name: {CStr(IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)).IfNullOrEmpty(otherName)}") If .IncludedInCollection Then info &= $"[{ .CollectionName}]: " If Settings.FeedShowFriendlyNames Or Not DirectCast(.Self, UserDataBase).FeedIsUser Then - info &= $"{ .Site} - { .FriendlyName.IfNullOrEmpty(.Name)}" + info &= $"{site}{ .FriendlyName.IfNullOrEmpty(.Name).IfNullOrEmpty(otherName)}" Else - info &= $"{ .Site} - {IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)}" + info &= $"{site}{CStr(IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)).IfNullOrEmpty(otherName)}" End If End With End If diff --git a/SCrawler/Download/Feed/FeedSpecial.vb b/SCrawler/Download/Feed/FeedSpecial.vb index ae8d704..c283ec7 100644 --- a/SCrawler/Download/Feed/FeedSpecial.vb +++ b/SCrawler/Download/Feed/FeedSpecial.vb @@ -147,6 +147,7 @@ Namespace DownloadObjects Dim user As IUserData Dim path$ = InitialUser.File.CutPath.PathWithSeparator Dim pathNew$ = NewUser.File.CutPath.PathWithSeparator + Dim isSaved As Boolean = Item.IsSavedPosts If Item.UserInfo.Equals(InitialUser) Or Item.UserInfo.Equals(NewUser) Then If Item.Data.File.PathWithSeparator.Contains(path) Then data = Item.Data @@ -157,7 +158,7 @@ Namespace DownloadObjects user = Item.User End If If Not If(user?.IsSubscription, False) Then - Item = New UserMediaD(data, user, Item.Session, Item.Date) + Item = New UserMediaD(data, user, Item.Session, Item.Date) With {.IsSavedPosts = isSaved} Result = True Return Item End If @@ -174,8 +175,10 @@ Namespace DownloadObjects If indx >= 0 Then Dim m As UserMediaD = Items(indx) Dim mm As UserMedia = m.Data + Dim user As UserInfo = m.UserInfo mm.File = NewFile - m = New UserMediaD(mm, If(MCTOptions.ReplaceUserProfile_Profile, m.User), m.Session, m.Date) + m = New UserMediaD(mm, If(MCTOptions.ReplaceUserProfile_Profile, m.User), m.Session, m.Date) With {.IsSavedPosts = m.IsSavedPosts} + If MCTOptions.ReplaceUserProfile_Profile Is Nothing And m.IsSavedPosts Then m.UserInfo = user Items(indx) = m _FilesUpdated = True End If diff --git a/SCrawler/Download/Feed/FeedVideo.vb b/SCrawler/Download/Feed/FeedVideo.vb index a64e4ae..eac2c97 100644 --- a/SCrawler/Download/Feed/FeedVideo.vb +++ b/SCrawler/Download/Feed/FeedVideo.vb @@ -176,5 +176,9 @@ Namespace DownloadObjects ErrorsDescriber.Execute(EDP.SendToLog, ex, $"An error occurred while performing action [{ActionName}] on file [{MediaFile}]") End Try End Function + Private Sub MyVideo_DoubleClick(sender As Object, e As EventArgs) Handles MyVideo.DoubleClick + [Stop]() + OnDoubleClick(e) + End Sub End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Download/TDownloader.vb b/SCrawler/Download/TDownloader.vb index c89c07c..8650781 100644 --- a/SCrawler/Download/TDownloader.vb +++ b/SCrawler/Download/TDownloader.vb @@ -39,7 +39,7 @@ Namespace DownloadObjects #End Region Friend ReadOnly User As IUserData Friend ReadOnly Data As UserMedia - Friend ReadOnly UserInfo As UserInfo + Friend UserInfo As UserInfo Friend ReadOnly [Date] As Date Friend Session As Integer Friend IsSavedPosts As Boolean @@ -257,6 +257,13 @@ Namespace DownloadObjects ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadObjects.TDownloader.ClearSessions]") End Try End Sub + Friend Sub ResetSession() + Files.Clear() + _FilesSessionActual = Nothing + _FilesSessionChecked = True + _Session = 0 + _SessionSavedPosts = -1 + End Sub #End Region Friend ReadOnly Property Downloaded As List(Of IUserData) Private ReadOnly NProv As IFormatProvider diff --git a/SCrawler/Editors/GlobalSettingsForm.Designer.vb b/SCrawler/Editors/GlobalSettingsForm.Designer.vb index 087de6a..2a91b26 100644 --- a/SCrawler/Editors/GlobalSettingsForm.Designer.vb +++ b/SCrawler/Editors/GlobalSettingsForm.Designer.vb @@ -179,6 +179,7 @@ Namespace Editors Me.CH_FEED_SHOW_SPEC_MEDIAITEM = New System.Windows.Forms.CheckBox() Me.NUM_FEED_STORE_SESSION_DATA = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.NUM_FEED_SES_CURR_LOAD_LAST = New PersonalUtilities.Forms.Controls.TextBoxExtended() + Me.CH_FEED_ADD_SITE = New System.Windows.Forms.CheckBox() Me.TXT_YTDLP = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_FFMPEG = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CURL = New PersonalUtilities.Forms.Controls.TextBoxExtended() @@ -204,6 +205,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_FEED_ADD_TYPE = 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() @@ -949,10 +951,10 @@ Namespace Editors ' Me.CH_FEED_OPEN_LAST_MODE.AutoSize = True Me.CH_FEED_OPEN_LAST_MODE.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_OPEN_LAST_MODE.Location = New System.Drawing.Point(4, 195) + Me.CH_FEED_OPEN_LAST_MODE.Location = New System.Drawing.Point(4, 247) Me.CH_FEED_OPEN_LAST_MODE.Name = "CH_FEED_OPEN_LAST_MODE" Me.CH_FEED_OPEN_LAST_MODE.Size = New System.Drawing.Size(613, 19) - Me.CH_FEED_OPEN_LAST_MODE.TabIndex = 7 + Me.CH_FEED_OPEN_LAST_MODE.TabIndex = 9 Me.CH_FEED_OPEN_LAST_MODE.Text = "Open last mode (users or subscriptions)" TT_MAIN.SetToolTip(Me.CH_FEED_OPEN_LAST_MODE, "If disabled, the user mode will be used when initializing the feed.") Me.CH_FEED_OPEN_LAST_MODE.UseVisualStyleBackColor = True @@ -1062,10 +1064,10 @@ Namespace Editors ' Me.CH_FEED_UP_FILE_LOC_MOVE.AutoSize = True Me.CH_FEED_UP_FILE_LOC_MOVE.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_UP_FILE_LOC_MOVE.Location = New System.Drawing.Point(4, 273) + Me.CH_FEED_UP_FILE_LOC_MOVE.Location = New System.Drawing.Point(4, 325) Me.CH_FEED_UP_FILE_LOC_MOVE.Name = "CH_FEED_UP_FILE_LOC_MOVE" Me.CH_FEED_UP_FILE_LOC_MOVE.Size = New System.Drawing.Size(613, 19) - Me.CH_FEED_UP_FILE_LOC_MOVE.TabIndex = 10 + Me.CH_FEED_UP_FILE_LOC_MOVE.TabIndex = 12 Me.CH_FEED_UP_FILE_LOC_MOVE.Text = "Update file location when moved" TT_MAIN.SetToolTip(Me.CH_FEED_UP_FILE_LOC_MOVE, "The file location will be updated in the session data and in the feeds data") Me.CH_FEED_UP_FILE_LOC_MOVE.UseVisualStyleBackColor = True @@ -1611,7 +1613,7 @@ Namespace Editors TAB_FEED.Controls.Add(TP_FEED) TAB_FEED.Location = New System.Drawing.Point(4, 22) TAB_FEED.Name = "TAB_FEED" - TAB_FEED.Size = New System.Drawing.Size(621, 399) + TAB_FEED.Size = New System.Drawing.Size(621, 374) TAB_FEED.TabIndex = 7 TAB_FEED.Text = "Feed" ' @@ -1623,32 +1625,35 @@ Namespace Editors TP_FEED.Controls.Add(TP_FEED_IMG_COUNT, 0, 0) TP_FEED.Controls.Add(Me.CH_FEED_ENDLESS, 0, 3) TP_FEED.Controls.Add(Me.CH_FEED_ADD_SESSION, 0, 4) - TP_FEED.Controls.Add(Me.CH_FEED_ADD_DATE, 0, 5) + TP_FEED.Controls.Add(Me.CH_FEED_ADD_DATE, 0, 7) TP_FEED.Controls.Add(Me.TXT_FEED_CENTER_IMAGE, 0, 1) TP_FEED.Controls.Add(Me.COLORS_FEED, 0, 2) - TP_FEED.Controls.Add(Me.CH_FEED_OPEN_LAST_MODE, 0, 7) - TP_FEED.Controls.Add(Me.CH_FEED_SHOW_FRIENDLY, 0, 8) - TP_FEED.Controls.Add(Me.CH_FEED_SHOW_SPEC_MEDIAITEM, 0, 9) - TP_FEED.Controls.Add(Me.CH_FEED_UP_FILE_LOC_MOVE, 0, 10) - TP_FEED.Controls.Add(TP_FEED_SES, 0, 6) + TP_FEED.Controls.Add(Me.CH_FEED_OPEN_LAST_MODE, 0, 9) + TP_FEED.Controls.Add(Me.CH_FEED_SHOW_FRIENDLY, 0, 10) + TP_FEED.Controls.Add(Me.CH_FEED_SHOW_SPEC_MEDIAITEM, 0, 11) + TP_FEED.Controls.Add(Me.CH_FEED_UP_FILE_LOC_MOVE, 0, 12) + TP_FEED.Controls.Add(TP_FEED_SES, 0, 8) + TP_FEED.Controls.Add(Me.CH_FEED_ADD_SITE, 0, 5) + TP_FEED.Controls.Add(Me.CH_FEED_ADD_TYPE, 0, 6) TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill TP_FEED.Location = New System.Drawing.Point(0, 0) TP_FEED.Name = "TP_FEED" - TP_FEED.RowCount = 12 + TP_FEED.RowCount = 14 TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) + TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) + TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) - TP_FEED.Size = New System.Drawing.Size(621, 399) + TP_FEED.Size = New System.Drawing.Size(621, 374) TP_FEED.TabIndex = 0 ' 'TP_FEED_IMG_COUNT @@ -1726,10 +1731,10 @@ Namespace Editors ' Me.CH_FEED_ADD_DATE.AutoSize = True Me.CH_FEED_ADD_DATE.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_ADD_DATE.Location = New System.Drawing.Point(4, 140) + Me.CH_FEED_ADD_DATE.Location = New System.Drawing.Point(4, 192) Me.CH_FEED_ADD_DATE.Name = "CH_FEED_ADD_DATE" Me.CH_FEED_ADD_DATE.Size = New System.Drawing.Size(613, 19) - Me.CH_FEED_ADD_DATE.TabIndex = 5 + Me.CH_FEED_ADD_DATE.TabIndex = 7 Me.CH_FEED_ADD_DATE.Text = "Add the date to the post title" Me.CH_FEED_ADD_DATE.UseVisualStyleBackColor = True ' @@ -1769,10 +1774,10 @@ Namespace Editors ' Me.CH_FEED_SHOW_FRIENDLY.AutoSize = True Me.CH_FEED_SHOW_FRIENDLY.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_SHOW_FRIENDLY.Location = New System.Drawing.Point(4, 221) + Me.CH_FEED_SHOW_FRIENDLY.Location = New System.Drawing.Point(4, 273) Me.CH_FEED_SHOW_FRIENDLY.Name = "CH_FEED_SHOW_FRIENDLY" Me.CH_FEED_SHOW_FRIENDLY.Size = New System.Drawing.Size(613, 19) - Me.CH_FEED_SHOW_FRIENDLY.TabIndex = 8 + Me.CH_FEED_SHOW_FRIENDLY.TabIndex = 10 Me.CH_FEED_SHOW_FRIENDLY.Text = "Show friendly names instead of usernames" Me.CH_FEED_SHOW_FRIENDLY.UseVisualStyleBackColor = True ' @@ -1780,10 +1785,10 @@ Namespace Editors ' Me.CH_FEED_SHOW_SPEC_MEDIAITEM.AutoSize = True Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Location = New System.Drawing.Point(4, 247) + Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Location = New System.Drawing.Point(4, 299) Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Name = "CH_FEED_SHOW_SPEC_MEDIAITEM" Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Size = New System.Drawing.Size(613, 19) - Me.CH_FEED_SHOW_SPEC_MEDIAITEM.TabIndex = 9 + Me.CH_FEED_SHOW_SPEC_MEDIAITEM.TabIndex = 11 Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Text = "Show special feeds in media items" Me.CH_FEED_SHOW_SPEC_MEDIAITEM.UseVisualStyleBackColor = True ' @@ -1795,14 +1800,14 @@ Namespace Editors TP_FEED_SES.Controls.Add(Me.NUM_FEED_STORE_SESSION_DATA, 0, 0) TP_FEED_SES.Controls.Add(Me.NUM_FEED_SES_CURR_LOAD_LAST, 1, 0) TP_FEED_SES.Dock = System.Windows.Forms.DockStyle.Fill - TP_FEED_SES.Location = New System.Drawing.Point(1, 163) + TP_FEED_SES.Location = New System.Drawing.Point(1, 215) TP_FEED_SES.Margin = New System.Windows.Forms.Padding(0) TP_FEED_SES.Name = "TP_FEED_SES" TP_FEED_SES.RowCount = 1 TP_FEED_SES.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FEED_SES.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_FEED_SES.Size = New System.Drawing.Size(619, 28) - TP_FEED_SES.TabIndex = 6 + TP_FEED_SES.TabIndex = 8 ' 'NUM_FEED_STORE_SESSION_DATA ' @@ -1851,6 +1856,17 @@ Namespace Editors Me.NUM_FEED_SES_CURR_LOAD_LAST.TabIndex = 1 Me.NUM_FEED_SES_CURR_LOAD_LAST.Text = "0" ' + 'CH_FEED_ADD_SITE + ' + Me.CH_FEED_ADD_SITE.AutoSize = True + Me.CH_FEED_ADD_SITE.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_FEED_ADD_SITE.Location = New System.Drawing.Point(4, 140) + Me.CH_FEED_ADD_SITE.Name = "CH_FEED_ADD_SITE" + Me.CH_FEED_ADD_SITE.Size = New System.Drawing.Size(613, 19) + Me.CH_FEED_ADD_SITE.TabIndex = 5 + Me.CH_FEED_ADD_SITE.Text = "Add the site name to the post title" + Me.CH_FEED_ADD_SITE.UseVisualStyleBackColor = True + ' 'TAB_NOTIFY ' TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN) @@ -2419,7 +2435,7 @@ Namespace Editors Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0) Me.TAB_MAIN.Name = "TAB_MAIN" Me.TAB_MAIN.SelectedIndex = 0 - Me.TAB_MAIN.Size = New System.Drawing.Size(629, 425) + Me.TAB_MAIN.Size = New System.Drawing.Size(629, 400) Me.TAB_MAIN.TabIndex = 1 ' 'TAB_ENVIR @@ -2437,7 +2453,7 @@ Namespace Editors 'CONTAINER_MAIN.ContentPanel ' Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN) - Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(629, 425) + Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(629, 400) Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) @@ -2447,6 +2463,17 @@ Namespace Editors Me.CONTAINER_MAIN.TabIndex = 0 Me.CONTAINER_MAIN.TopToolStripPanelVisible = False ' + 'CH_FEED_ADD_TYPE + ' + Me.CH_FEED_ADD_TYPE.AutoSize = True + Me.CH_FEED_ADD_TYPE.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_FEED_ADD_TYPE.Location = New System.Drawing.Point(4, 166) + Me.CH_FEED_ADD_TYPE.Name = "CH_FEED_ADD_TYPE" + Me.CH_FEED_ADD_TYPE.Size = New System.Drawing.Size(613, 19) + Me.CH_FEED_ADD_TYPE.TabIndex = 6 + Me.CH_FEED_ADD_TYPE.Text = "Add the file type to the post title" + Me.CH_FEED_ADD_TYPE.UseVisualStyleBackColor = True + ' 'GlobalSettingsForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -2660,5 +2687,7 @@ Namespace Editors Private WithEvents CH_CHANNELS_USERS_READY_MARK As CheckBox Private WithEvents NUM_FEED_SES_CURR_LOAD_LAST As PersonalUtilities.Forms.Controls.TextBoxExtended Private WithEvents TXT_AUTO_BRUSH_MIN As PersonalUtilities.Forms.Controls.TextBoxExtended + Private WithEvents CH_FEED_ADD_SITE As CheckBox + Private WithEvents CH_FEED_ADD_TYPE 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 6dd713b..838d512 100644 --- a/SCrawler/Editors/GlobalSettingsForm.vb +++ b/SCrawler/Editors/GlobalSettingsForm.vb @@ -151,6 +151,8 @@ Namespace Editors COLORS_FEED.ColorsSet(.FeedBackColor, .FeedForeColor, SystemColors.Window, SystemColors.WindowText) CH_FEED_ENDLESS.Checked = .FeedEndless CH_FEED_ADD_SESSION.Checked = .FeedAddSessionToCaption + CH_FEED_ADD_SITE.Checked = .FeedAddSiteToCaption + CH_FEED_ADD_TYPE.Checked = .FeedAddTypeToCaption CH_FEED_ADD_DATE.Checked = .FeedAddDateToCaption NUM_FEED_STORE_SESSION_DATA.Checked = .FeedStoreSessionsData NUM_FEED_STORE_SESSION_DATA.Value = .FeedStoredSessionsNumber.Value @@ -361,6 +363,8 @@ Namespace Editors COLORS_FEED.ColorsGet(.FeedBackColor, .FeedForeColor) .FeedEndless.Value = CH_FEED_ENDLESS.Checked .FeedAddSessionToCaption.Value = CH_FEED_ADD_SESSION.Checked + .FeedAddSiteToCaption.Value = CH_FEED_ADD_SITE.Checked + .FeedAddTypeToCaption.Value = CH_FEED_ADD_TYPE.Checked .FeedAddDateToCaption.Value = CH_FEED_ADD_DATE.Checked .FeedStoreSessionsData.Value = NUM_FEED_STORE_SESSION_DATA.Checked .FeedStoredSessionsNumber.Value = NUM_FEED_STORE_SESSION_DATA.Value diff --git a/SCrawler/MainMod.vb b/SCrawler/MainMod.vb index b9ec1d0..60d2d1f 100644 --- a/SCrawler/MainMod.vb +++ b/SCrawler/MainMod.vb @@ -77,6 +77,12 @@ Friend Module MainMod ''' Alt+F1 Friend ReadOnly ShowUsersButtonKey As New PersonalUtilities.Forms.ButtonKey(Keys.F1,, True) Friend ReadOnly DateTimeDefaultProvider As New ADateTime(ADateTime.Formats.BaseDateTime) + Friend Function ToStringDateDef(ByVal _DateN As Date?) As String + Return If(_DateN.HasValue, AConvert(Of String)(_DateN, DateTimeDefaultProvider, String.Empty), String.Empty) + End Function + Friend Function ToStringDateDef(ByVal _Date As Date) As String + Return ToStringDateDef(_DateN:=_Date) + End Function Friend ReadOnly SessionDateTimeProvider As New ADateTime("yyyyMMdd_HHmmss") Friend ReadOnly FeedVideoLengthProvider As New ADateTime("hh\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan} Friend ReadOnly LogConnector As New LogHost diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb index 50ab392..f00c2f0 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/SettingsCLS.vb b/SCrawler/SettingsCLS.vb index 33db66e..10ad0dd 100644 --- a/SCrawler/SettingsCLS.vb +++ b/SCrawler/SettingsCLS.vb @@ -402,6 +402,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable FeedForeColor.SetExtended("FeedColorFore",, MyXML, n) FeedEndless = New XMLValue(Of Boolean)("Endless", True, MyXML, n) FeedAddSessionToCaption = New XMLValue(Of Boolean)("AddSessionToCaption", False, MyXML, n) + FeedAddSiteToCaption = New XMLValue(Of Boolean)("AddSiteToCaption", True, MyXML, n) + FeedAddTypeToCaption = New XMLValue(Of Boolean)("AddTypeToCaption", False, MyXML, n) FeedAddDateToCaption = New XMLValue(Of Boolean)("AddDateToCaption", True, MyXML, n) FeedStoreSessionsData = New XMLValue(Of Boolean)("StoreSessionsData", True, MyXML, n) FeedStoredSessionsNumber = New XMLValue(Of Integer)("StoredSessionsNumber", 20, MyXML, n) @@ -1260,6 +1262,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable Friend ReadOnly Property FeedForeColor As XMLValue(Of Color) Friend ReadOnly Property FeedEndless As XMLValue(Of Boolean) Friend ReadOnly Property FeedAddSessionToCaption As XMLValue(Of Boolean) + Friend ReadOnly Property FeedAddSiteToCaption As XMLValue(Of Boolean) + Friend ReadOnly Property FeedAddTypeToCaption As XMLValue(Of Boolean) Friend ReadOnly Property FeedAddDateToCaption As XMLValue(Of Boolean) Friend ReadOnly Property FeedStoreSessionsData As XMLValue(Of Boolean) Friend ReadOnly Property FeedStoredSessionsNumber As XMLValue(Of Integer)