AOI/main.go

289 lines
9.9 KiB
Go

package main
import (
"crypto/rand"
"fmt"
"log"
"math/big"
"net/http"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"syscall"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/elazarl/goproxy"
)
var (
AoiApp fyne.App
AoiJan fyne.Window
VSCode bool
CodeBlocks bool
Python bool
Home string
)
type TextGridWriter struct {
TextGridWidget *widget.TextGrid
}
func (tw *TextGridWriter) Write(p []byte) (n int, err error) {
logMsg := string(p)
tw.TextGridWidget.SetText(tw.TextGridWidget.Text() + logMsg)
return len(p), nil
}
func proxy() {
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = true
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("boca.facom.*:443$"))).HandleConnect(goproxy.FuncHttpsHandler(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
return goproxy.OkConnect, host
}))
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(".*:443$"))).HandleConnect(goproxy.AlwaysReject)
randport, _ := rand.Int(rand.Reader, (big.NewInt(65535 - 40000 + 1)))
portaAleatoria := fmt.Sprintf("%v", randport)
strPorta, _ := strconv.Atoi(portaAleatoria)
strPorta += 40000
fmt.Printf("%v", strPorta)
log.Fatal(http.ListenAndServe(":8080", proxy))
}
func main() {
Home, _ = os.UserHomeDir()
aoi := app.NewWithID("br.ufu.facom.boca.aoi")
AoiApp = aoi
aoiJanela := aoi.NewWindow("AOI - Apenas Outro Instalador")
AoiJan = aoiJanela
aoiJanela.CenterOnScreen()
aoiJanela.SetMaster()
aoiJanela.RequestFocus()
aoiJanela.Resize(fyne.Size{Height: 644, Width: 866})
aoiJanela.SetIcon(resourceIconPng)
AoiApp.SetIcon(resourceIconPng)
aoiJanela.SetCloseIntercept(func() {
aoiJanela.Hide()
})
tituloPaginaPrincipal := widget.NewRichTextFromMarkdown(textoPaginaPrincipal)
//tituloPaginaPrincipal.Wrapping = fyne.TextWrapWord
btnProximoPaginaPrincipal := widget.NewButtonWithIcon("Iniciar", theme.NavigateNextIcon(), func() { mudarPagina(1) })
btnProximoPaginaPrincipal.IconPlacement = widget.ButtonIconTrailingText
btnProximoPaginaPrincipal.Importance = widget.SuccessImportance
if desk, ok := AoiApp.(desktop.App); ok {
m := fyne.NewMenu("AOI",
fyne.NewMenuItem("Mostrar", func() {
AoiJan.Show()
}),
fyne.NewMenuItemSeparator(),
fyne.NewMenuItem("Quit", func() {
AoiJan.Show()
sairSenha := dialog.NewEntryDialog("Opa, chama o seu professor!", "Digite a senha de acesso.", func(s string) {
if s == "facom" {
scriptMatarProxy, _ := os.CreateTemp("", "AOI_PROXY_REMOVE_*.cmd")
scriptMatarProxy.WriteString(scriptRemoverProxy)
scriptMatarProxy.Sync()
scriptMatarProxy.Close()
removerProxy := exec.Command("cmd", "/c", scriptMatarProxy.Name())
removerProxy.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
removerProxy.Run()
AoiApp.Quit()
}
}, AoiJan)
sairSenha.Show()
}))
desk.SetSystemTrayMenu(m)
}
aoiJanela.SetContent(container.NewCenter(container.NewVBox(tituloPaginaPrincipal, btnProximoPaginaPrincipal)))
aoiJanela.ShowAndRun()
}
func mudarPagina(x int) {
switch x {
case 1:
//Começa a instalar o scoop
labelStatus := widget.NewLabel("Criando script de instalação...")
actv := widget.NewProgressBarInfinite()
actv.Start()
barraStatus := container.NewStack(labelStatus, actv)
registroStdout := widget.NewTextGrid()
AoiJan.SetContent(container.NewBorder(barraStatus, nil, nil, nil, container.NewScroll(registroStdout)))
textGridWidgetWriter := &TextGridWriter{TextGridWidget: registroStdout}
log.SetPrefix("")
log.SetOutput(textGridWidgetWriter)
command := exec.Command("powershell", "-c", "Set-ExecutionPolicy", "-ExecutionPolicy", "Unrestricted", "-Scope", "CurrentUser")
command.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
command.Stdin = strings.NewReader("s\n")
command.Run()
log.Print("[Debug] ExecutionPolicy: ")
command = exec.Command("powershell", "-c", "Get-ExecutionPolicy")
command.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
out, _ := command.CombinedOutput()
log.Printf("%s", out)
command.Run()
log.Println("Instalando scoop, isso pode demorar um pouco...")
git7zip, _ := os.CreateTemp("", "AOI_*.ps1")
git7zip.WriteString(scriptInstalação)
git7zip.Sync()
git7zip.Close()
git7zipInstall := exec.Command("powershell", "-c", git7zip.Name())
git7zipInstall.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
out, _ = git7zipInstall.CombinedOutput()
log.Printf("%s", out)
git7zipInstall.Run()
log.Println("==== INSTALAÇÃO PRONTA =====")
barraStatus.RemoveAll()
barraStatus.Add(widget.NewButtonWithIcon("Continuar", theme.NavigateNextIcon(), func() { mudarPagina(2) }))
case 2:
labelTituloSelecionarIde := widget.NewLabel("\tSelecione qual IDE você quer utilizar.")
labelTituloSelecionarIde.TextStyle = fyne.TextStyle{Bold: true}
btnSelecionarIdeVsc := widget.NewButtonWithIcon("Visual Studio Code", resourceVscodePng, func() { VSCode = true; mudarPagina(3) })
btnSelecionarIdeVsc.Importance = widget.HighImportance
btnSelecionarIdeCb := widget.NewButtonWithIcon("Code::Blocks", resourceCodeblocksPng, func() { CodeBlocks = true; mudarPagina(3) })
btnSelecionarIdeCb.Importance = widget.HighImportance
conteudoPagina := container.NewCenter(container.NewBorder(labelTituloSelecionarIde, nil, nil, nil, container.NewGridWithColumns(2, btnSelecionarIdeVsc, btnSelecionarIdeCb)))
AoiJan.SetContent(conteudoPagina)
case 3:
labelTituloSelecionarLang := widget.NewLabel("\tEscolha qual linguagem irá utilizar.")
labelTituloSelecionarLang.TextStyle = fyne.TextStyle{Bold: true}
chkSelecionarCpp := &widget.Check{Text: "C/C++"}
imgSelecionarCpp := canvas.NewImageFromResource(resourceCppPng)
imgSelecionarCpp.FillMode = canvas.ImageFillOriginal
imgAndChkSelecionarCpp := container.NewBorder(nil, nil, imgSelecionarCpp, nil, chkSelecionarCpp)
chkSelecionarPython := &widget.Check{Text: "Python 3.10"}
imgSelecionarPython := canvas.NewImageFromResource(resourcePythonPng)
imgSelecionarPython.FillMode = canvas.ImageFillOriginal
imgAndChkSelecionarPython := container.NewBorder(nil, nil, imgSelecionarPython, nil, chkSelecionarPython)
if CodeBlocks {
chkSelecionarPython.Disable()
chkSelecionarCpp.SetChecked(true)
}
btnProximaPagina := widget.NewButtonWithIcon("Instalar IDE e linguagem(s)", theme.NavigateNextIcon(), func() {
if !chkSelecionarCpp.Checked && !chkSelecionarPython.Checked {
dialog.ShowInformation("Escolha uma linguagem", "Escolha pelo menos uma linguagem para prosseguir.", AoiJan)
return
}
mudarPagina(4)
})
btnProximaPagina.IconPlacement = widget.ButtonIconTrailingText
btnProximaPagina.Importance = widget.HighImportance
AoiJan.SetContent(container.NewCenter(container.NewBorder(labelTituloSelecionarLang, btnProximaPagina, nil, nil, container.NewGridWithRows(2, imgAndChkSelecionarCpp, imgAndChkSelecionarPython))))
case 4:
labelStatus := widget.NewLabel("Instalando linguagens e ide...")
barraProgresso := widget.NewProgressBarInfinite()
barraProgresso.Start()
barraStatus := container.NewStack(labelStatus, barraProgresso)
registroStdout := widget.NewTextGrid()
escrivãoRegistro := &TextGridWriter{TextGridWidget: registroStdout}
log.SetOutput(escrivãoRegistro)
AoiJan.SetContent(container.NewBorder(barraStatus, nil, nil, nil, container.NewScroll(registroStdout)))
switch {
case CodeBlocks:
log.Println("[Info] Instalando Code::Blocks com GCC...")
instalarVSCode := exec.Command("cmd", "/c", "scoop", "install", "extras/codeblocks-mingw")
instalarVSCode.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
instalarVSCode.Dir = Home + "\\scoop\\shims"
out, _ := instalarVSCode.CombinedOutput()
log.Printf("%s", out)
instalarVSCode.Run()
case VSCode:
log.Println("[Info] Instalando Visual Studio Code...")
instalarVSCode := exec.Command("scoop", "install", "extras/vscode")
instalarVSCode.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
instalarVSCode.Dir = Home + "\\scoop\\shims"
out, _ := instalarVSCode.CombinedOutput()
log.Printf("%s", out)
instalarVSCode.Run()
case Python:
log.Println("[Info] Instalando Python 3.10...")
instalarPython := exec.Command("scoop", "install", "versions/python310")
instalarPython.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
instalarPython.Dir = Home + "\\scoop\\shims"
out, _ := instalarPython.CombinedOutput()
log.Printf("%s", out)
instalarPython.Run()
log.Println("[Info] [Python] Mesclando entrada no registro....")
mesclarRegistro := exec.Command("reg", "merge", fmt.Sprintf("%s\\scoop\\apps\\python310\\current\\install-pep-514.reg", Home))
mesclarRegistro.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
mesclarRegistro.Run()
case VSCode && !Python:
log.Println("[Info] Instalando GCC...")
instalarGcc := exec.Command("scoop", "install", "versions/tdm-gcc")
instalarGcc.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
instalarGcc.Dir = Home + "\\scoop\\shims"
out, _ := instalarGcc.CombinedOutput()
log.Printf("%s", out)
instalarGcc.Run()
}
barraStatus.RemoveAll()
barraStatus.Add(widget.NewButtonWithIcon("Continuar", theme.NavigateNextIcon(), func() { mudarPagina(5) }))
case 5:
labelFim := widget.NewRichTextFromMarkdown(`# Tudo pronto!
Agora você já pode começar sua prova!`)
btnIniciarProxy := widget.NewButtonWithIcon("Fechar o app", theme.WindowCloseIcon(), func() {
proxyScript, _ := os.CreateTemp("", "AOI_PROXY_*.cmd")
proxyScript.WriteString(scriptProxy)
proxyScript.Sync()
proxyScript.Close()
ativarProxy := exec.Command("cmd", "/c", proxyScript.Name())
ativarProxy.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
ativarProxy.Start()
go func() {
proxy()
}()
AoiJan.Hide()
})
btnIniciarProxy.Importance = widget.DangerImportance
AoiJan.SetContent(container.NewVBox(labelFim, btnIniciarProxy))
}
}