From 56748f043e596ba79e745139dbfe0504e3d4eec1 Mon Sep 17 00:00:00 2001 From: Belac Darkstorm Date: Wed, 9 Aug 2017 03:36:35 -0500 Subject: [PATCH] Added stuff for appimages. Shows changelog before updating. --- app.go | 34 ++++++++++++--- appimg/download.go | 1 + main.go | 20 +++++++-- settings.go | 44 ++++++++++++++++++++ update.go | 101 ++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 185 insertions(+), 15 deletions(-) diff --git a/app.go b/app.go index bde1302..41befdf 100644 --- a/app.go +++ b/app.go @@ -53,6 +53,10 @@ func (a *app) launch() { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; wine \""+a.ex[0]+"\"") } } else { + if paDirs && strings.HasSuffix(strings.ToLower(a.ex[0]), ".appimage") { + os.Mkdir(a.dir+"/"+a.ex[0]+".home", 0777) + os.Mkdir(a.dir+"/"+a.ex[0]+".config", 0777) + } if comEnbld { cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"") } else { @@ -64,8 +68,12 @@ func (a *app) launch() { cmd.Start() } else { var cmd *exec.Cmd + if paDirs && strings.HasSuffix(strings.ToLower(a.ex[0]), ".appimage") { + os.Mkdir(a.dir+"/"+a.ex[0]+".home", 0777) + os.Mkdir(a.dir+"/"+a.ex[0]+".config", 0777) + } if comEnbld { - cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"") + cmd = exec.Command("/bin/sh", "-c", "export PANAME="+a.ex[0]+";. PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"") } else { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"") } @@ -90,8 +98,12 @@ func (a *app) launch() { break } } + if paDirs && strings.HasSuffix(strings.ToLower(a.ex[ind]), ".appimage") { + os.Mkdir(a.dir+"/"+a.ex[ind]+".home", 0777) + os.Mkdir(a.dir+"/"+a.ex[ind]+".config", 0777) + } if comEnbld { - cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"") + cmd = exec.Command("/bin/sh", "-c", "export PANAME="+a.ex[ind]+";. PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"") } else { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"") } @@ -109,8 +121,12 @@ func (a *app) launch() { } } var cmd *exec.Cmd + if paDirs && strings.HasSuffix(strings.ToLower(a.ex[ind]), ".appimage") { + os.Mkdir(a.dir+"/"+a.ex[ind]+".home", 0777) + os.Mkdir(a.dir+"/"+a.ex[ind]+".config", 0777) + } if comEnbld { - cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"") + cmd = exec.Command("/bin/sh", "-c", "export PANAME="+a.ex[ind]+";. PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"") } else { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"") } @@ -132,8 +148,12 @@ func (a *app) launchSub(sub int) { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; wine \""+a.ex[sub]+"\"") } } else { + if paDirs && strings.HasSuffix(strings.ToLower(a.ex[sub]), ".appimage") { + os.Mkdir(a.dir+"/"+a.ex[sub]+".home", 0777) + os.Mkdir(a.dir+"/"+a.ex[sub]+".config", 0777) + } if comEnbld { - cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"") + cmd = exec.Command("/bin/sh", "-c", "export PANAME="+a.ex[sub]+";. PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"") } else { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"") } @@ -143,8 +163,12 @@ func (a *app) launchSub(sub int) { cmd.Start() } else { var cmd *exec.Cmd + if paDirs && strings.HasSuffix(strings.ToLower(a.ex[sub]), ".appimage") { + os.Mkdir(a.dir+"/"+a.ex[sub]+".home", 0777) + os.Mkdir(a.dir+"/"+a.ex[sub]+".config", 0777) + } if comEnbld { - cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"") + cmd = exec.Command("/bin/sh", "-c", "export PANAME="+a.ex[sub]+";. PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"") } else { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"") } diff --git a/appimg/download.go b/appimg/download.go index 33f7291..ec60c0c 100644 --- a/appimg/download.go +++ b/appimg/download.go @@ -39,6 +39,7 @@ func downloadApp(parent *gtk.Window, ap appimg) { return nil }, } + fmt.Println(urlBase + ap.full) resp, err := check.Get(urlBase + ap.full) if err != nil { fmt.Println(err) diff --git a/main.go b/main.go index 267985c..8c664c5 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "encoding/gob" + "flag" "fmt" "os" @@ -9,7 +10,7 @@ import ( ) const ( - version = "2.1.1.0" + version = "2.1.2.0" defIni = "" ) @@ -23,16 +24,19 @@ var ( wineAvail bool portableHide bool versionNewest = true + paDirs = true ) func main() { + forced := flag.Bool("force-update", false, "Force the update dialog to be shown") + flag.Parse() os.MkdirAll("PortableApps/LinuxPACom", 0777) master = make(map[string][]app) linmaster = make(map[string][]app) - uiStart() + uiStart(*forced) } -func uiStart() { +func uiStart(forced bool) { gtk.Init(nil) setup() win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) @@ -49,7 +53,7 @@ func uiStart() { ui(win) win.ShowAll() win.Show() - update(win) + update(win, forced) gtk.Main() } @@ -72,6 +76,10 @@ func savePrefs() { if err != nil { return } + err = enc.Encode(paDirs) + if err != nil { + return + } } func loadPrefs() { @@ -92,6 +100,10 @@ func loadPrefs() { if err != nil { return } + err = dec.Decode(&paDirs) + if err != nil { + return + } } func contains(arr []string, str string) bool { diff --git a/settings.go b/settings.go index add75dc..2273c72 100644 --- a/settings.go +++ b/settings.go @@ -9,6 +9,10 @@ import ( "github.com/gotk3/gotk3/gtk" ) +const ( + commonHelp = "The common.sh is run before every app is launched and allows you to set variables such as $HOME. For directories, ALWAYS start the directory with $PWD which points to the directory where LinuxPA is. To allow for greater customization and isolation, you can use the $PANAME variable which is the filename of the executable you're using." +) + func settingsUI(parent *gtk.Window, onExit func()) { win, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) win.SetTransientFor(parent) @@ -84,11 +88,17 @@ func settingsUI(parent *gtk.Window, onExit func()) { versCheck.Connect("toggled", func() { versionNewest = versCheck.GetActive() }) + paDirsCheck, _ := gtk.CheckButtonNewWithLabel("Create .home and .config directories for AppImages") + paDirsCheck.SetActive(paDirs) + paDirsCheck.Connect("toggled", func() { + paDirs = paDirsCheck.GetActive() + }) gnrl.Add(wineLbl) gnrl.Add(dlWine) gnrl.Add(pthdCheck) gnrl.Add(wineCheck) gnrl.Add(versCheck) + gnrl.Add(paDirsCheck) ntbk.AppendPage(gnrl, getLabel("General")) com, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5) com.SetMarginStart(10) @@ -113,8 +123,25 @@ func settingsUI(parent *gtk.Window, onExit func()) { cnl.Connect("clicked", func() { setupTxt(comBuf) }) + info, _ := gtk.ButtonNewWithLabel("Info") + info.Connect("clicked", func() { + infoBox, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + infoBox.SetTransientFor(parent) + infoBox.SetDefaultSize(300, 80) + infoBox.SetName("common.sh info") + infoBox.SetPosition(gtk.WIN_POS_CENTER_ON_PARENT) + box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5) + infolbl, _ := gtk.LabelNew(commonHelp) + infolbl.SetLineWrap(true) + infolbl.SetSizeRequest(200, 50) + box.Add(infolbl) + infoBox.Add(box) + infoBox.ShowAll() + infoBox.Show() + }) svBox.Add(sv) svBox.Add(cnl) + svBox.Add(info) com.Add(comScrl) com.Add(svBox) ntbk.AppendPage(com, getLabel("common.sh")) @@ -136,8 +163,25 @@ func settingsUI(parent *gtk.Window, onExit func()) { dlWine.SetTooltipText("") } }) + in, _ := gtk.ButtonNewWithLabel("Info") + in.Connect("clicked", func() { + infoBox, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + infoBox.SetTransientFor(parent) + infoBox.SetDefaultSize(300, 80) + infoBox.SetName("common.sh info") + infoBox.SetPosition(gtk.WIN_POS_CENTER_ON_PARENT) + box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5) + infolbl, _ := gtk.LabelNew(commonHelp) + infolbl.SetLineWrap(true) + infolbl.SetSizeRequest(200, 50) + box.Add(infolbl) + infoBox.Add(box) + infoBox.ShowAll() + infoBox.Show() + }) mkCom.Show() com.Add(mkCom) + com.Add(in) } else { setupTxt(comBuf) } diff --git a/update.go b/update.go index 3b4a31e..8c6564e 100644 --- a/update.go +++ b/update.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "io" + "io/ioutil" "net/http" "os" "os/exec" @@ -14,8 +15,9 @@ import ( ) const ( - versionURL = "https://www.dropbox.com/s/a0xizzo0a4vsfqt/Version?dl=1" - downloadURL = "https://github.com/CalebQ42/LinuxPA/releases/download/vXXX/LinuxPA" + versionURL = "https://www.dropbox.com/s/a0xizzo0a4vsfqt/Version?dl=1" + downloadURL = "https://github.com/CalebQ42/LinuxPA/releases/download/vXXX/LinuxPA" + changelogURL = "https://www.dropbox.com/s/nmbk318er5kej5h/Changelog?dl=1" ) //Thanks to https://www.socketloop.com/tutorials/golang-download-file-example @@ -55,6 +57,38 @@ func getVersionFileInfo() string { return string(out) } +func changelogDL() (bool, error) { + changelogFile, err := os.Create("PortableApps/LinuxPACom/Changelog") + if err != nil { + return false, err + } + changelogFile.Chmod(0777) + check := http.Client{ + CheckRedirect: func(r *http.Request, via []*http.Request) error { + r.URL.Opaque = r.URL.Path + return nil + }, + } + response, err := check.Get(changelogURL) + if err != nil { + return false, err + } + _, err = io.Copy(changelogFile, response.Body) + if err != nil { + return false, err + } + return true, nil +} + +func getChangelog() string { + fil, err := os.Open("PortableApps/LinuxPACom/Changelog") + if err != nil { + return "Error!" + } + out, _ := ioutil.ReadAll(fil) + return string(out) +} + func checkForUpdate(new string) (bool, error) { curSlice := strings.Split(version, ".") newSlice := strings.Split(new, ".") @@ -111,13 +145,69 @@ func downloadUpdate(newVersion string) (bool, error) { return true, nil } -func update(win *gtk.Window) { +func update(win *gtk.Window, forced bool) { + stat, err := versionDL() + if stat { + res := getVersionFileInfo() + if res != "Error!" { + stat, err = checkForUpdate(res) + if stat || forced { + stat, err = changelogDL() + if stat { + updateWin, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + updateWin.SetTransientFor(win) + updateWin.SetPosition(gtk.WIN_POS_CENTER) + topLvl, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5) + lbl, _ := gtk.LabelNew("There's a new update! Here's the changelog:") + tagTbl, _ := gtk.TextTagTableNew() + buf, _ := gtk.TextBufferNew(tagTbl) + tv, _ := gtk.TextViewNewWithBuffer(buf) + tv.SetEditable(false) + buf.SetText(getChangelog()) + butBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 5) + upBut, _ := gtk.ButtonNewWithLabel("Update") + upBut.Connect("clicked", func() { + updateWin.Close() + actuallyUpdate(win, forced) + }) + cnlBut, _ := gtk.ButtonNewWithLabel("Cancel") + cnlBut.Connect("clicked", func() { + updateWin.Close() + }) + butBox.Add(upBut) + butBox.Add(cnlBut) + topLvl.Add(lbl) + topLvl.Add(tv) + topLvl.Add(butBox) + topLvl.SetMarginBottom(10) + topLvl.SetMarginEnd(10) + topLvl.SetMarginStart(10) + topLvl.SetMarginTop(10) + updateWin.Add(topLvl) + updateWin.ShowAll() + updateWin.Show() + } else { + fmt.Println(err) + } + } else { + fmt.Println(err) + } + } else { + fmt.Println("Failed Version File Info") + } + } else { + fmt.Println(err) + } +} + +func actuallyUpdate(win *gtk.Window, forced bool) { updateWin, _ := gtk.WindowNew(gtk.WINDOW_POPUP) updateWin.SetTransientFor(win) + updateWin.SetSizeRequest(150, 50) topLvl, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5) spin, _ := gtk.SpinnerNew() spin.Start() - lbl, _ := gtk.LabelNew("Checking for updates") + lbl, _ := gtk.LabelNew("Updating") topLvl.Add(spin) topLvl.Add(lbl) topLvl.SetMarginBottom(10) @@ -135,8 +225,7 @@ func update(win *gtk.Window) { res := getVersionFileInfo() if res != "Error!" { stat, err = checkForUpdate(res) - if stat { - lbl.SetText("Updating!") + if stat || forced { downloadUpdate(res) win.Close() cmd := exec.Command("./LinuxPA")