mirror of
https://github.com/AAndyProgram/SCrawler.git
synced 2026-03-14 15:52:18 +00:00
229 lines
13 KiB
VB.net
229 lines
13 KiB
VB.net
' Copyright (C) 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.Net
|
|
Imports System.IO.Compression
|
|
Imports PersonalUtilities.Functions
|
|
Imports PersonalUtilities.Functions.XML
|
|
Imports PersonalUtilities.Tools.Web.Clients
|
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
|
Imports SCrawler.Shared
|
|
Public Module MainMod
|
|
Private MyProcessID As Integer = -1
|
|
Private MyWorkingPath As SFile = Nothing
|
|
Private ReadOnly ProcessNames As String() = {"SCrawler", "YouTubeDownloader", "Updater"}
|
|
Private Silent As Boolean = False
|
|
Private Function GetConsoleResponse(ByVal Request As String) As String
|
|
Console.Write(Request)
|
|
Return Console.ReadLine
|
|
End Function
|
|
Private Function DownloadFile(ByVal URL As String, ByVal Destination As SFile) As Boolean
|
|
Try
|
|
Dim lastPerc% = -1
|
|
Dim currentCursor% = Console.CursorTop
|
|
Using w As New RWebClient With {.AsyncMode = True}
|
|
AddHandler w.DownloadProgressChanged,
|
|
New DownloadProgressChangedEventHandler(Sub(ByVal Sender As Object, ByVal e As DownloadProgressChangedEventArgs)
|
|
If lastPerc < e.ProgressPercentage Then
|
|
lastPerc = e.ProgressPercentage
|
|
Console.SetCursorPosition(0, currentCursor)
|
|
Console.Write("{0}% completed", e.ProgressPercentage)
|
|
End If
|
|
End Sub)
|
|
Return w.DownloadFile(URL, Destination, EDP.ReturnValue)
|
|
End Using
|
|
Catch ex As Exception
|
|
Return False
|
|
End Try
|
|
End Function
|
|
Public Sub Main()
|
|
Try
|
|
MyWorkingPath = AppDomain.CurrentDomain.BaseDirectory.CSFileP
|
|
MyProcessID = Process.GetCurrentProcess.Id
|
|
Console.Title = "SCrawler updater"
|
|
With Environment.GetCommandLineArgs
|
|
If .ListExists(2) Then Silent = .Self()(1).FromXML(Of Boolean)(False)
|
|
End With
|
|
|
|
Dim currentDir As SFile = MyWorkingPath.CutPath
|
|
Dim extractionDir As SFile = $"{currentDir.CSFilePS}{NewReleaseFolderName}\"
|
|
If extractionDir.Exists(SFO.Path, False) Then extractionDir.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
|
|
|
Dim currVer As Version = GetCurrentMaxVer(currentDir)
|
|
If currVer Is Nothing Then
|
|
Console.WriteLine("The current version of the program cannot be determined")
|
|
Else
|
|
Console.WriteLine($"The current version is {currVer} (x{IIf(Environment.Is64BitProcess, 64, 86)})")
|
|
Dim release As GitRelease = GetGitRelease()
|
|
If Not release.URL.IsEmptyString And Not release.Version Is Nothing Then
|
|
If release.Version > currVer Then
|
|
Console.WriteLine($"The new version is {release.Version} ({release.Name})")
|
|
|
|
If Not Silent AndAlso GetConsoleResponse("Do you want to update the program? (y/n): ").IfNullOrEmpty("n") = "n" Then Exit Sub
|
|
|
|
If ActiveProcessesExist() Then
|
|
Console.WriteLine("One of the SCrawler programs is still running. Waiting for all SCrawler programs to close.")
|
|
While ActiveProcessesExist() : Threading.Thread.Sleep(100) : End While
|
|
Console.WriteLine("All SCrawler programs are closed.")
|
|
End If
|
|
|
|
If extractionDir.Exists(SFO.Path, True) Then
|
|
Dim destFile As SFile = $"{extractionDir.CSFilePS}{New SFile(release.URL).File}"
|
|
Console.WriteLine("Downloading new version...")
|
|
If DownloadFile(release.URL, destFile) Then
|
|
Console.WriteLine("")
|
|
Console.WriteLine("New version downloaded!")
|
|
Console.WriteLine("Extracting files...")
|
|
ZipFile.ExtractToDirectory(destFile, extractionDir)
|
|
Console.WriteLine("Files extracted!")
|
|
destFile.Delete(SFO.File, SFODelete.DeletePermanently, EDP.None)
|
|
If Not MoveFiles(extractionDir, currentDir) Then GetConsoleResponse("Unable to update the program. Press Enter to exit") : Exit Sub
|
|
Else
|
|
extractionDir.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
|
Console.WriteLine("Unable to download new version")
|
|
End If
|
|
Else
|
|
Console.WriteLine("Unable to create temp directory")
|
|
End If
|
|
Else
|
|
Console.WriteLine("The program is up to date")
|
|
End If
|
|
Else
|
|
Console.WriteLine("Unable to get information about new version")
|
|
End If
|
|
End If
|
|
Catch ex As Exception
|
|
Console.WriteLine("An error occurred during update")
|
|
Console.WriteLine(ex.Message)
|
|
Finally
|
|
GetConsoleResponse("Press Enter to exit")
|
|
End Try
|
|
End Sub
|
|
Private Function MoveFiles(ByVal Source As SFile, ByVal Destination As SFile) As Boolean
|
|
Console.WriteLine("Updating files")
|
|
Try
|
|
|
|
Dim oldFiles As List(Of SFile) = SFile.GetFiles(Destination,,, EDP.ReturnValue)
|
|
Dim oldFolders As List(Of SFile) = SFile.GetDirectories(Destination,,, EDP.ReturnValue)
|
|
|
|
Dim newFiles As List(Of SFile) = SFile.GetFiles(Source,,, EDP.ReturnValue)
|
|
Dim newFolders As List(Of SFile) = SFile.GetDirectories(Source,,, EDP.ReturnValue)
|
|
|
|
Dim obj As SFile = Nothing
|
|
Dim wSegment As String = MyWorkingPath.Segments.Last
|
|
Dim filesPredicate As Predicate(Of SFile) = Function(ByVal f As SFile) As Boolean
|
|
If obj = f Or obj.Name = f.Name Then
|
|
f.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None)
|
|
Return True
|
|
Else
|
|
Return False
|
|
End If
|
|
End Function
|
|
Dim foldersPredicate As Predicate(Of SFile) = Function(ByVal f As SFile) As Boolean
|
|
Dim ls$ = f.Segments.Last
|
|
If ls = obj.Segments.Last And Not ls = NewReleaseFolderName And Not ls = wSegment Then
|
|
f.Delete(SFO.Path, SFODelete.DeleteToRecycleBin, EDP.None)
|
|
Return True
|
|
Else
|
|
Return False
|
|
End If
|
|
End Function
|
|
|
|
Dim getDestFile As Func(Of SFile, Boolean, SFile) = Function(ByVal f As SFile, ByVal isFolder As Boolean) As SFile
|
|
Dim ff As SFile = f
|
|
If isFolder Then
|
|
ff = $"{Destination.PathWithSeparator}{f.Segments.Last}\"
|
|
Else
|
|
ff.Path = Destination.Path
|
|
End If
|
|
Console.WriteLine(ff)
|
|
Return ff
|
|
End Function
|
|
If newFiles.ListExists Then
|
|
If oldFiles.ListExists Then
|
|
For Each obj In newFiles : oldFiles.RemoveAll(filesPredicate) : Next
|
|
End If
|
|
newFiles.ForEach(Sub(ff) SFile.Move(ff, getDestFile(ff, False), SFO.File, True, SFODelete.DeleteToRecycleBin, EDP.None))
|
|
End If
|
|
|
|
If newFolders.ListExists Then
|
|
If oldFolders.ListExists Then
|
|
For Each obj In newFolders : oldFolders.RemoveAll(foldersPredicate) : Next
|
|
End If
|
|
newFolders.ForEach(Sub(ff) If Not ff.Segments.Last = wSegment Then _
|
|
SFile.Move(ff, getDestFile(ff, True), SFO.Path, True, SFODelete.DeleteToRecycleBin, EDP.None))
|
|
End If
|
|
|
|
Console.WriteLine("Files updated")
|
|
Return True
|
|
Catch
|
|
Return False
|
|
End Try
|
|
End Function
|
|
Private Function ActiveProcessesExist() As Boolean
|
|
Try
|
|
Return Process.GetProcesses.Any(Function(p) ProcessNames.Contains(p.ProcessName) And Not p.Id = MyProcessID)
|
|
Catch
|
|
Return True
|
|
End Try
|
|
End Function
|
|
Private Structure GitRelease
|
|
Friend URL As String
|
|
Friend Name As String
|
|
Friend Version As Version
|
|
End Structure
|
|
Private Function GetGitRelease() As GitRelease
|
|
Try
|
|
Dim nameEnd$ = $"_x{IIf(Environment.Is64BitProcess, 64, 86)}.zip"
|
|
Dim name$, relName$, relTag$
|
|
|
|
Using resp As New Responser With {.Accept = "application/vnd.github.v3+json"}
|
|
Dim r$ = resp.GetResponse("https://api.github.com/repos/AAndyProgram/SCrawler/releases",, EDP.ReturnValue)
|
|
If Not r.IsEmptyString Then
|
|
Dim getver As Func(Of String, Version) = Function(ByVal input As String) As Version
|
|
Try
|
|
If Not input.IsEmptyString Then
|
|
If input.ToLower.StartsWith("scrawler") Then
|
|
Return New Version(input.Split("_")(1))
|
|
Else
|
|
Return New Version(input)
|
|
End If
|
|
End If
|
|
Catch
|
|
End Try
|
|
Return Nothing
|
|
End Function
|
|
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
|
If j.ListExists Then
|
|
With j.FirstOrDefault(Function(e) Not e.Value("draft").FromXML(Of Boolean) And Not e.Value("prerelease").FromXML(Of Boolean))
|
|
If .ListExists Then
|
|
relName = .Value("name")
|
|
relTag = .Value("tag_name")
|
|
With .Item("assets")
|
|
If .ListExists Then
|
|
For Each asset As EContainer In .Self
|
|
name = asset.Value("name")
|
|
If Not name.IsEmptyString AndAlso name.EndsWith(nameEnd) Then _
|
|
Return New GitRelease With {
|
|
.Name = name,
|
|
.URL = asset.Value("browser_download_url"),
|
|
.Version = getver(name).IfNullOrEmpty(getver(relName).IfNullOrEmpty(getver(relTag)))}
|
|
Next
|
|
End If
|
|
End With
|
|
End If
|
|
End With
|
|
End If
|
|
End Using
|
|
End If
|
|
End Using
|
|
Catch
|
|
End Try
|
|
Return Nothing
|
|
End Function
|
|
End Module |