2023.4.28.0

Plugins
IPluginContentProvider: added DownloadSingleObject function; added tokens to GetMedia and Download functions; removed GetSpecialData function
Add IDownloadableMedia interface
Removed 'Channel' option from all functions and enums
ISiteSettings: added GetSingleMediaInstance function
ExchangeOptions: removed 'IsChannel'
UserMediaTypes: added Audio and AudioPre enums
IUserMedia, PluginUserMedia: changed ContentType and DownloadState from integers to their enums

SCrawler
Add YouTube standalone downloader
Add gallery-dl & yt-dlp support
Remove 'UserInfo' requirement from 'ProfilesSaved'
Update 'SiteSettingsBase' to use domains and Netscape cookies
UserDataBase: remove channels; remove old 'Merge' const; standardize SavedPosts file naming; move 'ValidateMD5' function from Twitter to UserDataBase to use it in other UserData classes; add 'DownloadSingleObject' environment for single posts; add validating file extension for m3u8 during download; add reindex of video file during download

Rewritten DomainsContainer
Create a universal settings form and PSettingsArttribute
Gfycat, Imgur: turn these classes into IUserData to download a single object

All plugins: update 'GetInstance' function for saved posts; update domains where implemented; remove 'OptionForm' where it exists; update options where they exist; update unix date providers; reconfigure channels where they exist

LPSG: fix attachments; update converters and regex
Add sites: ThisVid, Mastodon, Pinterest, YouTube, YouTube music
Reddit: standardize container parsing for all data types; new channel environment; fix 'ReparseMissing' function; redirect data downloading to the base download function, saved crossposts support
Twitter: fixed gif path bug; fixed downloading saved posts
PornHub: hide unnecessary errors; photo galleries bug
RedGifs: add 'UserAgent' option

Added icons to download progress

Rename some objects
Completely redesigned standalone downloader form and rewritten its environment
WebClient2: update to use tokens

Labels: update label form (save labels to file only when OK button is clicked); change removing labels.txt from recycle bin to permanent; disable storing label 'NoParsedUser'

UserCreatorForm: remove the 'Channel' checkbox and related functions; ability to extract the user's URL from the buffer and apply parameters if found
Remove temporary 'EncryptCookies' module

MainFrame: added simplified way to create new users (Ctrl+Insert to create a new user with default parameters from clipboard URL); removed SCrawler command line argument "-v" (remove the ability to run SCrawler as video downloader)
PropertyValueHost: update for option forms compatibility
SettingsHost: removed 'GetSpecialData' fork; added 'GetSingleMediaInstance' fork
UserDataHost: update functions with tokens; update events; add 'DownloadSingleObject' function
Settings: add the ability to get environment from 4 destinations; add the ability to set the program environment manually; add CMDEncoding; add cache; remove the old function 'RemoveUnusedPlugins'; add 'STDownloader' properties; add YT compatibility; add new notification options; add deleting user settings file when 'SettingsCLS.Dispose()' if where are no users in SCrawler
UserFinder: remove old 'Merge' const; remove channel option
UserInfo: remove channel option
This commit is contained in:
Andy
2023-04-28 10:13:46 +03:00
parent db9e2cfb88
commit b2a9b22478
270 changed files with 18120 additions and 3332 deletions

View File

@@ -12,60 +12,30 @@ Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Tools.Web
Imports SCrawler.API
Imports SCrawler.API.Base
Imports SCrawler.Plugin.Hosts
Imports SCrawler.DownloadObjects
Friend Module MainMod
Friend Settings As SettingsCLS
Friend Const SettingsFolderName As String = "Settings"
Friend Const SettingsFolderName As String = XML.XmlFile.SettingsFolder
Friend ReadOnly LinkPattern As RParams = RParams.DMS("[htps:]{0,6}[/]{0,2}(.+)", 1)
Friend ReadOnly FilesPattern As RParams = RParams.DM("[^\./]+?\.\w+", 1, EDP.ReturnValue)
Friend Delegate Sub NotificationEventHandler(ByVal Sender As SettingsCLS.NotificationObjects, ByVal Message As String)
Friend Const LVI_TempOption As String = "Temp"
Friend Const LVI_FavOption As String = "Favorite"
Friend Const CannelsLabelName As String = "Channels"
Friend Const LVI_CollectionOption As String = "Collection"
Friend Const LVI_ChannelOption As String = "Channel"
Friend Property BATCH As BatchExecutor
Private _BatchLogSent As Boolean = False
''' <param name="e"><see cref="EDP.None"/></param>
Friend Sub GlobalOpenPath(ByVal f As SFile, Optional ByVal e As ErrorsDescriber = Nothing)
Dim b As Boolean = False
If Not e.Exists Then e = EDP.None
Try
If f.Exists(SFO.Path, False) Then
If Settings.OpenFolderInOtherProgram.Attribute.Value AndAlso Not Settings.OpenFolderInOtherProgram.IsEmptyString Then
If BATCH Is Nothing Then BATCH = New BatchExecutor With {.RedirectStandardError = True}
b = True
With BATCH
.Reset()
.Execute({String.Format(Settings.OpenFolderInOtherProgram.Value, f.PathWithSeparator)}, EDP.SendInLog + EDP.ThrowException)
If .HasError Or Not .ErrorOutput.IsEmptyString Then Throw New Exception(.ErrorOutput, .ErrorException)
End With
Else
f.Open(SFO.Path, e)
End If
End If
Catch ex As Exception
If b Then
If Not _BatchLogSent Then ErrorsDescriber.Execute(EDP.SendInLog, ex, $"GlobalOpenPath({f.Path})") : _BatchLogSent = True
f.Open(SFO.Path, e)
End If
End Try
End Sub
Friend Sub ExecuteCommand(ByVal Obj As XMLValueAttribute(Of String, Boolean))
Try
If Obj.Attribute And Not Obj.IsEmptyString Then
Using b As New BatchExecutor With {.RedirectStandardError = True}
With b
.Execute({Obj.Value}, EDP.SendInLog + EDP.ThrowException)
.Execute({Obj.Value}, EDP.SendToLog + EDP.ThrowException)
If .HasError Or Not .ErrorOutput.IsEmptyString Then Throw New Exception(.ErrorOutput, .ErrorException)
End With
End Using
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendInLog, ex, $"[{Obj.Name}] command: [{Obj.Value}]")
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[{Obj.Name}] command: [{Obj.Value}]")
End Try
End Sub
Friend Enum ViewModes As Integer
@@ -100,7 +70,7 @@ Friend Module MainMod
End Enum
Friend Downloader As TDownloader
Friend InfoForm As DownloadedInfoForm
Friend VideoDownloader As VideosDownloaderForm
Friend VideoDownloader As STDownloader.VideoDownloaderForm
Friend UserListLoader As ListImagesLoader
Friend MyProgressForm As ActiveDownloadingProgress
Friend MainFrameObj As MainFrameObjects
@@ -121,19 +91,18 @@ Friend Module MainMod
End Class
#End Region
Friend Property MainProgress As MyProgress
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal IsCollection As Boolean, ByVal IsChannel As Boolean) As ListViewGroup()
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal IsCollection As Boolean) As ListViewGroup()
Dim l As New List(Of ListViewGroup)
Dim t$
t = GetLviGroupName(Host, False, True, IsCollection, IsChannel)
t = GetLviGroupName(Host, False, True, IsCollection)
l.Add(New ListViewGroup(t, t))
t = GetLviGroupName(Host, False, False, IsCollection, IsChannel)
t = GetLviGroupName(Host, False, False, IsCollection)
l.Add(New ListViewGroup(t, t))
t = GetLviGroupName(Host, True, False, IsCollection, IsChannel)
t = GetLviGroupName(Host, True, False, IsCollection)
l.Add(New ListViewGroup(t, t))
Return l.ToArray
End Function
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal Temp As Boolean, ByVal Fav As Boolean,
ByVal IsCollection As Boolean, ByVal IsChannel As Boolean) As String
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal Temp As Boolean, ByVal Fav As Boolean, ByVal IsCollection As Boolean) As String
Dim Opt$ = String.Empty
If Temp Then
Opt = LVI_TempOption
@@ -143,8 +112,6 @@ Friend Module MainMod
If Not Opt.IsEmptyString Then Opt = $" ({Opt})"
If IsCollection Then
Return $"{LVI_CollectionOption}{Opt}"
ElseIf IsChannel Then
Return $"{LVI_ChannelOption}{Opt}"
Else
Return $"{If(Host?.Name, String.Empty)}{Opt}"
End If
@@ -157,113 +124,6 @@ Friend Module MainMod
Return Nothing
End If
End Function
#Region "Standalone video download functions"
Friend Function GetCurrentBuffer() As String
Dim b$ = BufferText
If Not (Not b.IsEmptyString AndAlso b.Length > 4 AndAlso b.StartsWith("http")) Then b = String.Empty
Return b
End Function
Friend Function DownloadVideoByURL(ByVal URL As String, ByVal AskForPath As Boolean, ByVal Silent As Boolean) As Boolean
Dim e As New ErrorsDescriber(Not Silent, Not Silent, True, False)
Try
Dim Result As Boolean = False
If Not URL.IsEmptyString Then
Dim um As IEnumerable(Of UserMedia) = Nothing
Dim found As Boolean = False
Dim d As Plugin.ExchangeOptions
If Settings.Plugins.Count > 0 Then
For Each p As PluginHost In Settings.Plugins
d = p.Settings.IsMyImageVideo(URL)
If d.Exists Then
um = Settings(d.HostKey).GetSpecialData(URL, Settings.LatestSavingPath.Value, AskForPath)
found = True
If um.ListExists Then
If AskForPath And Not um(0).SpecialFolder.IsEmptyString Then Settings.LatestSavingPath.Value = um(0).SpecialFolder
If um(0).State = UserMedia.States.Downloaded Then Return True
End If
Exit For
End If
Next
End If
If Not found Then
If URL.Contains("gfycat") Then
um = Gfycat.Envir.GetVideoInfo(URL)
If um.ListExists AndAlso um(0).URL.Contains("redgifs.com") Then Return DownloadVideoByURL(um(0).URL, AskForPath, Silent)
ElseIf URL.Contains("imgur.com") Then
um = Imgur.Envir.GetVideoInfo(URL)
Else
MsgBoxE("Site of video URL not recognized" & vbCr & "Operation canceled", MsgBoxStyle.Exclamation, e)
Return False
End If
End If
If um.ListExists Then
Dim f As SFile, ff As SFile
Dim dURL$
Dim FileDownloaded As Boolean = False
For Each u As UserMedia In um
If Not u.URL.IsEmptyString Or Not u.URL_BASE.IsEmptyString Then
f = u.File
If f.Name.IsEmptyString Then f.Name = $"video_{u.Post.ID}"
If f.Extension.IsEmptyString Then f.Extension = "mp4"
If Not Settings.LatestSavingPath.IsEmptyString And
Settings.LatestSavingPath.Value.Exists(SFO.Path, False) Then f.Path = Settings.LatestSavingPath.Value
If AskForPath OrElse Not f.Exists(SFO.Path, False) Then
#Disable Warning BC40000
ff = SFile.SaveAs(f, "Files destination",,,, EDP.ReturnValue)
#Enable Warning
If Not ff.IsEmptyString Then
f.Path = ff.Path
Else
f = Nothing
End If
AskForPath = False
End If
If Not f.IsEmptyString Then
Settings.LatestSavingPath.Value = f.PathWithSeparator
FileDownloaded = False
Using w As New Net.WebClient
For i% = 0 To 1
If i = 0 Then dURL = u.URL Else dURL = u.URL_BASE
If Not dURL.IsEmptyString Then
Try
w.DownloadFile(dURL, f)
FileDownloaded = True
Exit For
Catch wex As Exception
ErrorsDescriber.Execute(EDP.SendInLog, wex, "DownloadVideoByURL")
End Try
End If
Next
End Using
If FileDownloaded Then
If um.Count = 1 Then
MsgBoxE($"File downloaded to [{f}]",, e)
Return True
Else
Result = True
End If
Else
If um.Count = 1 Then MsgBoxE("File not downloaded", MsgBoxStyle.Critical, e)
End If
Else
If um.Count = 1 Then MsgBoxE("File destination not specified" & vbCr & "Operation canceled",, e)
End If
Else
If um.Count = 1 Then MsgBoxE("File URL not found!", MsgBoxStyle.Critical, e)
End If
Next
End If
Else
MsgBoxE("URL is empty", MsgBoxStyle.Exclamation, e)
End If
Return Result
Catch ex As Exception
Return ErrorsDescriber.Execute(e, ex, $"Error when trying to download video from URL: [{URL}]", False)
End Try
End Function
#End Region
Friend Sub CheckVersion(ByVal Force As Boolean)
If Settings.CheckUpdatesAtStart Or Force Then _
GitHub.DefaultVersionChecker(My.Application.Info.Version, "AAndyProgram", "SCrawler",