Files
SCrawler/SCrawler.YouTube/Controls/MusicPlaylistsForm.vb
Andy 0ec617c1dc 2023.11.21.0
YouTube
Add absolute paths support
PlaylistArrayForm: fix RTB issue
Single media: the file name is not changed manually

SCrawler
Automation: add manual tasks
DownloaderUrlsArrForm: fix RTB issue
SiteSettingsBase: add use of Netscape cookies if enabled for a class; disable saving Netscape cookies on init
Add feeds update when users' location and/or basic info changes
API.TikTok: add ID, username and friendly name extraction from data; update request URL; update 'GetUserUrl' function; add new option 'Use video date as file date'
API.YouTube: set 'UseNetscapeCookies'
2023-11-21 09:25:22 +03:00

292 lines
15 KiB
VB.net

' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports SCrawler.API.YouTube.Objects
Imports SCrawler.DownloadObjects.STDownloader
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls
Imports PersonalUtilities.Forms.Controls.Base
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace API.YouTube.Controls
Friend Class MusicPlaylistsForm : Implements IDesignXMLContainer
#Region "Declarations"
Private MyView As FormView
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
Private ReadOnly MyContainer As IYouTubeMediaContainer
Private Initializing As Boolean = True
Private ReadOnly Property Current As IYouTubeMediaContainer
Get
With MyContainer
If .ObjectType = Base.YouTubeMediaType.Channel Then
If _LatestSelected.ValueBetween(0, .Count - 1) Then Return .Elements(_LatestSelected)
Else
Return .Self
End If
End With
Return Nothing
End Get
End Property
#End Region
#Region "Initializer"
Friend Sub New(ByVal Container As IYouTubeMediaContainer)
InitializeComponent()
MyContainer = Container
End Sub
#End Region
#Region "Form handlers"
Private Sub MusicPlaylistsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not DesignXML Is Nothing Then
MyView = New FormView(Me)
MyView.Import()
MyView.SetFormSize()
End If
MyYouTubeSettings.DownloadLocations.PopulateComboBox(TXT_OUTPUT_PATH)
CMB_FORMATS.Items.AddRange(AvailableAudioFormats)
If MyYouTubeSettings.PlaylistFormSplitterDistance > 0 Then SPLITTER_MAIN.SplitterDistancePercentageSet(MyYouTubeSettings.PlaylistFormSplitterDistance)
With MyContainer
CH_DOWN_LYRICS.Checked = Not .OutputSubtitlesFormat.IsEmptyString
Dim i%
If Not .OutputAudioCodec.IsEmptyString Then
i = AvailableAudioFormats.ListIndexOf(Function(ff) ff.StringToLower = .OutputAudioCodec.StringToLower)
If i >= 0 Then CMB_FORMATS.SelectedIndex = i
End If
If CMB_FORMATS.SelectedIndex = -1 Then
Dim oac$ = MyYouTubeSettings.DefaultAudioCodecMusic.Value.IfNullOrEmpty("mp3").StringToLower
i = AvailableAudioFormats.ListIndexOf(Function(ff) ff.StringToLower = oac)
If i >= 0 Then CMB_FORMATS.SelectedIndex = i Else CMB_FORMATS.SelectedIndex = 0
End If
If .ObjectType = Base.YouTubeMediaType.Channel Then
If .HasElements Then
For Each elem In .Elements : LIST_PLAYLISTS.Items.Add(elem, elem.CheckState) : Next
End If
ElseIf .ObjectType = Base.YouTubeMediaType.PlayList Then
LIST_PLAYLISTS.Items.Add(.Self, .CheckState)
Else
Throw New InvalidOperationException($"The object type '{ .ObjectType}' is incompatible with 'MusicPlaylistsForm'.")
End If
LIST_PLAYLISTS.SelectedIndex = 0
If .ObjectType = Base.YouTubeMediaType.Channel Then
With TXT_OUTPUT_PATH
.CaptionMode = ICaptionControl.Modes.Label
.CaptionToolTipText = String.Empty
.CaptionToolTipEnabled = False
End With
End If
TXT_OUTPUT_PATH.Text = MyYouTubeSettings.OutputPath.Value
If Not .UserTitle.IsEmptyString Then
Text = .UserTitle
If .ObjectType = Base.YouTubeMediaType.PlayList Then
If Not .PlaylistTitle.IsEmptyString AndAlso Not .PlaylistTitle = .UserTitle Then
Text &= $" - { .PlaylistTitle}"
ElseIf Not .Title.IsEmptyString AndAlso Not .Title = .UserTitle Then
Text &= $" - { .Title}"
End If
End If
If Not TXT_OUTPUT_PATH.IsEmptyString AndAlso Not TXT_OUTPUT_PATH.Text.Contains(.UserTitle) Then TXT_OUTPUT_PATH.Text = $"{TXT_OUTPUT_PATH.Text.TrimEnd("\")}\{ .UserTitle}\"
ElseIf Not .PlaylistTitle.IsEmptyString Then
Text = .PlaylistTitle
End If
UpdateSizeText()
End With
RefillAddit()
Initializing = False
End Sub
Private Sub MusicPlaylistsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
MyYouTubeSettings.PlaylistFormSplitterDistance.Value = SPLITTER_MAIN.SplitterDistancePercentageGet
MyView.DisposeIfReady()
End Sub
Private Sub MusicPlaylistsForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True
If e.KeyCode = Keys.O And e.Control Then
MyYouTubeSettings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT_PATH, False, MyDownloaderSettings.OutputPathAskForName)
ElseIf e.KeyCode = Keys.O And e.Alt Then
MyYouTubeSettings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT_PATH, True, MyDownloaderSettings.OutputPathAskForName)
Else
b = False
End If
If b Then e.Handled = True
End Sub
#End Region
#Region "Form text"
Private _InitialFormText As String = String.Empty
Private Sub UpdateSizeText()
If _InitialFormText.IsEmptyString Then _InitialFormText = Text
Text = $"{_InitialFormText} ({MyContainer.SizeStr})"
End Sub
#End Region
#Region "Settings"
Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick, TXT_FORMATS_ADDIT.ActionOnButtonClick
Dim isLyrics As Boolean = DirectCast(e.AssociatedControl, Control).Tag = "s"
With DirectCast(MyContainer, YouTubeMediaContainerBase)
Select Case Sender.DefaultButton
Case ADB.Open
Using f As New SimpleListForm(Of String)(IIf(isLyrics, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
.DesignXML = DesignXML,
.DesignXMLNodeName = SimpleArraysFormNode,
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText,
.Icon = My.Resources.SiteYouTube.YouTubeMusicIcon_32,
.Mode = SimpleListFormModes.CheckedItems
}
f.DataSelected.ListAddList(IIf(isLyrics, .PostProcessing_OutputSubtitlesFormats, .PostProcessing_OutputAudioFormats))
If f.ShowDialog = DialogResult.OK Then
If isLyrics Then
.PostProcessing_OutputSubtitlesFormats.Clear()
.PostProcessing_OutputSubtitlesFormats.ListAddList(f.DataResult)
Else
.PostProcessing_OutputAudioFormats.Clear()
.PostProcessing_OutputAudioFormats.ListAddList(f.DataResult)
End If
RefillAddit()
End If
End Using
Case ADB.Refresh
If isLyrics Then
.PostProcessing_OutputSubtitlesFormats_Reset()
Else
.PostProcessing_OutputAudioFormats_Reset()
End If
RefillAddit()
Case ADB.Clear
If isLyrics Then
.PostProcessing_OutputSubtitlesFormats.Clear()
Else
.PostProcessing_OutputAudioFormats.Clear()
End If
RefillAddit()
End Select
End With
End Sub
Private Sub RefillAddit()
With DirectCast(MyContainer, YouTubeMediaContainerBase)
TXT_SUBS.Text = .PostProcessing_OutputSubtitlesFormats.ListToString
TXT_FORMATS_ADDIT.Text = .PostProcessing_OutputAudioFormats.ListToString
End With
End Sub
Private Sub TXT_OUTPUT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_OUTPUT_PATH.ActionOnButtonClick
If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _
MyYouTubeSettings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT_PATH, Sender.DefaultButton = ADB.Add, MyDownloaderSettings.OutputPathAskForName)
End Sub
#End Region
#Region "Lists' handlers"
Private _LatestSelected As Integer = -1
Private Sub LIST_PLAYLISTS_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_PLAYLISTS.SelectedIndexChanged
Dim i% = LIST_PLAYLISTS.SelectedIndex
If i >= 0 Then
_LatestSelected = i
LIST_ITEMS.Items.Clear()
With DirectCast(LIST_PLAYLISTS.SelectedItem, IYouTubeMediaContainer)
If .HasElements Then
For Each elem In .Elements : LIST_ITEMS.Items.Add(elem, elem.Checked) : Next
End If
End With
End If
End Sub
Private _CheckHandlersSuspended As Boolean = False
Private Sub LIST_PLAYLISTS_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles LIST_PLAYLISTS.ItemCheck
If Not Initializing And Not _CheckHandlersSuspended Then
_CheckHandlersSuspended = True
Dim checked As Boolean = Not e.NewValue = CheckState.Unchecked
Dim current As IYouTubeMediaContainer = Me.Current
If Not current Is Nothing Then
With current
.Checked = checked
If LIST_ITEMS.Items.Count > 0 Then
_ListCheckHandlersSuspended = True
For i% = 0 To .Count - 1
If i.ValueBetween(0, LIST_ITEMS.Items.Count - 1) Then LIST_ITEMS.SetItemChecked(i, checked)
Next
_ListCheckHandlersSuspended = False
End If
If LIST_PLAYLISTS.Items.Count.ValueBetween(0, _LatestSelected) Then LIST_PLAYLISTS.SetItemChecked(_LatestSelected, checked)
End With
UpdateSizeText()
End If
_CheckHandlersSuspended = False
End If
End Sub
Private _ListCheckHandlersSuspended As Boolean = False
Private Sub LIST_ITEMS_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles LIST_ITEMS.ItemCheck
If Not Initializing Then
Dim current As IYouTubeMediaContainer = Me.Current
If Not current Is Nothing Then
With current
If e.Index.ValueBetween(0, .Count - 1) Then
.Elements(e.Index).Checked = e.NewValue
If Not _ListCheckHandlersSuspended And _LatestSelected.ValueBetween(0, LIST_PLAYLISTS.Items.Count - 1) Then
Dim checked As Boolean = .Elements(e.Index).Checked
_CheckHandlersSuspended = True
If .Elements.All(Function(ee) ee.Checked = checked) Then
LIST_PLAYLISTS.SetItemChecked(_LatestSelected, checked)
Else
LIST_PLAYLISTS.SetItemCheckState(_LatestSelected, CheckState.Indeterminate)
End If
_CheckHandlersSuspended = False
LIST_PLAYLISTS.Refresh()
UpdateSizeText()
End If
End If
End With
End If
End If
End Sub
#End Region
#Region "Selection buttons"
Private Sub BTT_PLS_Click(sender As Object, e As EventArgs) Handles BTT_PLS_ALL.Click, BTT_PLS_NONE.Click
Dim checked As Boolean = DirectCast(sender, Button).Tag = "a"
_CheckHandlersSuspended = True
If LIST_PLAYLISTS.Items.Count > 0 Then
For i% = 0 To LIST_PLAYLISTS.Items.Count - 1 : LIST_PLAYLISTS.SetItemChecked(i, checked) : Next
End If
MyContainer.Checked = checked
If MyContainer.Count > 1 Then MyContainer.Elements.ForEach(Sub(ee) ee.Checked = checked)
_CheckHandlersSuspended = False
UpdateSizeText()
End Sub
#End Region
#Region "Ok, Cancel"
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
If TXT_OUTPUT_PATH.IsEmptyString Then
MsgBoxE({"The output path cannot be null.", "Download music"}, vbCritical)
Else
With DirectCast(MyContainer, YouTubeMediaContainerBase)
.OutputSubtitlesFormat = IIf(CH_DOWN_LYRICS.Checked, "LRC", String.Empty)
If Not TXT_SUBS.Checked Then .PostProcessing_OutputSubtitlesFormats.Clear()
.OutputAudioCodec = CMB_FORMATS.Text
If Not TXT_FORMATS_ADDIT.Checked Then .PostProcessing_OutputAudioFormats.Clear()
.AbsolutePath = TXT_OUTPUT_PATH.Checked
.File = TXT_OUTPUT_PATH.Text.CSFileP
If MyYouTubeSettings.OutputPathAutoChange Then MyYouTubeSettings.OutputPath.Value = .File
If MyDownloaderSettings.OutputPathAutoAddPaths Then MyYouTubeSettings.DownloadLocations.Add(.File, False)
End With
DialogResult = DialogResult.OK
Close()
End If
End Sub
Private Sub BTT_CANCEL_Click(sender As Object, e As EventArgs) Handles BTT_CANCEL.Click
DialogResult = DialogResult.Cancel
Close()
End Sub
#End Region
End Class
End Namespace