Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6723f933b4 | |||
| 016fc35745 | |||
| ba5e3510ec | |||
| 7e2d7ee14b | |||
| b20de4f1d6 | |||
| d2e91baa6b | |||
| a0f22e480b | |||
| 57f921c2cb | |||
| 55f897db46 | |||
| 3d9583281e | |||
| ec4d66f6b2 | |||
| c442ef5688 | |||
| 78d3723bf4 | |||
| 828b9f4cda | |||
| be64aa083f | |||
| 3111705cae |
@@ -6,7 +6,7 @@ Just double click on an app to launch it! If there are multiple executables, you
|
|||||||
|
|
||||||
# Apps:
|
# Apps:
|
||||||
The below place provides linux executables that don't need libs installed on the host system:
|
The below place provides linux executables that don't need libs installed on the host system:
|
||||||
[AppImage](https://bintray.com/probono/AppImages)
|
[https://appimage.github.io/](https://appimage.github.io/)
|
||||||
|
|
||||||
# PortableApps.com Compatibility
|
# PortableApps.com Compatibility
|
||||||
LinuxPA works will with the PortableApps.com launcher, as it looks for apps in the PortableApps folder and grabs the app's name and icon from where it should be in the PortableApps.com format.
|
LinuxPA works will with the PortableApps.com launcher, as it looks for apps in the PortableApps folder and grabs the app's name and icon from where it should be in the PortableApps.com format.
|
||||||
@@ -19,8 +19,8 @@ common.sh is found in the PortableApps/LinuxPACom folder and is executed before
|
|||||||
Because apps aren't natively formated in the PortableApps.com format, LinuxPA will look in the root directory for a AppInfo.ini (for basic info such as category and name) and appicon.png. If they aren't found, it looks where the appicon_\*.png and AppInfo.ini is in PortableApps format. You can set what the AppInfo.ini and appicon.png are from LinuxPA.
|
Because apps aren't natively formated in the PortableApps.com format, LinuxPA will look in the root directory for a AppInfo.ini (for basic info such as category and name) and appicon.png. If they aren't found, it looks where the appicon_\*.png and AppInfo.ini is in PortableApps format. You can set what the AppInfo.ini and appicon.png are from LinuxPA.
|
||||||
|
|
||||||
# AppImage Support
|
# AppImage Support
|
||||||
[AppImage Website](http://appimage.org)
|
[AppImage Website](http://appimage.org)
|
||||||
Right now AppImages are simply supported via the native linux executable support, and you can download AppImages. (Woo)
|
I'm looking into improving AppImage support. As of 2.1.5.0 IF `unsquashfs` is in $PATH then some advanced AppImage support is available and it will automagically get the name and possibly the icon of it. I'm looking into better support, but it might be a while.
|
||||||
|
|
||||||
# USB mount
|
# USB mount
|
||||||
Unfortunately Linux, by default, doesn't support running executables off of FAT formated flash drives, requiring you to mount your drive with special mount arguments or format in a linux friendly format (such as EXT4). I personally use the arguments `exec,noauto,nodev,nosuid,umask=0000`
|
Unfortunately Linux, by default, doesn't support running executables off of FAT formated flash drives, requiring you to mount your drive with special mount arguments or format in a linux friendly format (such as EXT4). I personally use the arguments `exec,noauto,nodev,nosuid,umask=0000`
|
||||||
@@ -30,6 +30,11 @@ Photos are found [Here](https://goo.gl/photos/VtBUL6DyZTMidj5n6). The screenshot
|
|||||||
|
|
||||||
# TODO (Might be in order)
|
# TODO (Might be in order)
|
||||||
1. MAKE IT BETTER
|
1. MAKE IT BETTER
|
||||||
|
1. Try to `chmod +x` executables if they don't have the permission
|
||||||
1. Manual update check
|
1. Manual update check
|
||||||
1. Better appimage support in general
|
1. Better AppImage integrations (Specifically updating, getting information from the appimage, and better appimage downloading)
|
||||||
|
1. Automagic appimage updating (It will of course ask you beforehand)
|
||||||
|
1. Get information (such as name and icon) directly from an appimage
|
||||||
|
1. Better appimage downloading (probably based around [AppImageHub](https://appimage.github.io/apps/))
|
||||||
|
1. Sandboxing support
|
||||||
1. Check if all apps are closed when it closes and ask if you want to force stop the apps
|
1. Check if all apps are closed when it closes and ask if you want to force stop the apps
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ type app struct {
|
|||||||
icon *gdk.Pixbuf
|
icon *gdk.Pixbuf
|
||||||
dir string
|
dir string
|
||||||
ini *os.File
|
ini *os.File
|
||||||
|
wine bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *app) getTreeIter(store *gtk.TreeStore) *gtk.TreeIter {
|
func (a *app) getTreeIter(store *gtk.TreeStore) *gtk.TreeIter {
|
||||||
it := store.Append(nil)
|
it := store.Append(nil)
|
||||||
store.SetValue(it, 0, a.icon)
|
scaled, _ := a.icon.ScaleSimple(32, 32, gdk.INTERP_HYPER)
|
||||||
|
store.SetValue(it, 0, scaled)
|
||||||
if portableHide {
|
if portableHide {
|
||||||
store.SetValue(it, 1, strings.TrimSuffix(a.name, "Portable"))
|
store.SetValue(it, 1, strings.TrimSuffix(a.name, "Portable"))
|
||||||
} else {
|
} else {
|
||||||
@@ -217,7 +219,7 @@ func (a *app) edit(parent *gtk.Window, reload func()) {
|
|||||||
fil.Close()
|
fil.Close()
|
||||||
})
|
})
|
||||||
resp := fil.Run()
|
resp := fil.Run()
|
||||||
if resp == int(gtk.RESPONSE_ACCEPT) {
|
if resp == gtk.RESPONSE_ACCEPT {
|
||||||
filename := fil.GetFilename()
|
filename := fil.GetFilename()
|
||||||
_, err := os.Open(filename)
|
_, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -242,7 +244,11 @@ func (a *app) edit(parent *gtk.Window, reload func()) {
|
|||||||
nameTxt.SetHExpand(true)
|
nameTxt.SetHExpand(true)
|
||||||
nameTxt.SetVExpand(false)
|
nameTxt.SetVExpand(false)
|
||||||
nameTxt.SetBorderWindowSize(gtk.TEXT_WINDOW_BOTTOM, 5)
|
nameTxt.SetBorderWindowSize(gtk.TEXT_WINDOW_BOTTOM, 5)
|
||||||
txtBuf.SetText(tmp.name)
|
nameShow := tmp.name
|
||||||
|
if tmp.wine {
|
||||||
|
nameShow = strings.TrimSuffix(nameShow, " (Wine)")
|
||||||
|
}
|
||||||
|
txtBuf.SetText(nameShow)
|
||||||
vScrollName, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
|
vScrollName, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
|
||||||
hScrollName, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
|
hScrollName, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
|
||||||
nameScr, _ := gtk.ScrolledWindowNew(hScrollName, vScrollName)
|
nameScr, _ := gtk.ScrolledWindowNew(hScrollName, vScrollName)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
module github.com/CalebQ42/LinuxPA
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/CalebQ42/GoAppImage v0.4.0
|
||||||
|
github.com/gotk3/gotk3 v0.5.0
|
||||||
|
github.com/mholt/archiver/v3 v3.5.0
|
||||||
|
github.com/pkg/browser v0.0.0-20201112035734-206646e67786
|
||||||
|
)
|
||||||
|
|
||||||
|
//For testing local changes to my library
|
||||||
|
// replace github.com/CalebQ42/GoAppImage => ../GoAppImage
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
github.com/CalebQ42/GoAppImage v0.4.0 h1:aF+Y/vyo/RGhoyZEW1CMY6WyRWrZZO4ydsRFAtIGnaY=
|
||||||
|
github.com/CalebQ42/GoAppImage v0.4.0/go.mod h1:qHudJKAn/dlkNWNnH4h1YKXp29EZ7Bppsn7sNP2HuvU=
|
||||||
|
github.com/adrg/xdg v0.2.2 h1:A7ZHKRz5KGOLJX/bg7IPzStryhvCzAE1wX+KWawPiAo=
|
||||||
|
github.com/adrg/xdg v0.2.2/go.mod h1:7I2hH/IT30IsupOpKZ5ue7/qNi3CoKzD6tL3HwpaRMQ=
|
||||||
|
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
|
||||||
|
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
||||||
|
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
||||||
|
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||||
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||||
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gotk3/gotk3 v0.5.0 h1:GOkq4cFgAfeK6YAukLi64bz8zPayZKeCSSRr4mcFReQ=
|
||||||
|
github.com/gotk3/gotk3 v0.5.0/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=
|
||||||
|
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
|
||||||
|
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
|
||||||
|
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
|
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
||||||
|
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
|
github.com/pierrec/lz4/v4 v4.0.3 h1:vNQKSVZNYUEAvRY9FaUXAF1XPbSOHJtDTiP41kzDz2E=
|
||||||
|
github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
|
github.com/pkg/browser v0.0.0-20201112035734-206646e67786 h1:4Gk0Dsp90g2YwfsxDOjvkEIgKGh+2R9FlvormRycveA=
|
||||||
|
github.com/pkg/browser v0.0.0-20201112035734-206646e67786/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||||
|
github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
|
||||||
|
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
|
go.lsp.dev/uri v0.3.0 h1:KcZJmh6nFIBeJzTugn5JTU6OOyG0lDOo3R9KwTxTYbo=
|
||||||
|
go.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/nelsam/gxui"
|
|
||||||
"github.com/nelsam/gxui/drivers/gl"
|
|
||||||
"github.com/nelsam/gxui/themes/dark"
|
|
||||||
"github.com/nelsam/gxui/themes/light"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
version = "1.1.0.0"
|
|
||||||
defIni = "[basic]\ntheme=dk"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
dr gxui.Driver
|
|
||||||
th gxui.Theme
|
|
||||||
master map[string][]app
|
|
||||||
linmaster map[string][]app
|
|
||||||
cats []string
|
|
||||||
lin []string
|
|
||||||
wine bool
|
|
||||||
comEnbld bool
|
|
||||||
darkTheme = true
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
updated := false
|
|
||||||
os.MkdirAll("PortableApps/LinuxPACom", 0777)
|
|
||||||
stat, err := versionDL()
|
|
||||||
if stat {
|
|
||||||
res := getVersionFileInfo()
|
|
||||||
if res != "Error!" {
|
|
||||||
stat, err = checkForUpdate(res)
|
|
||||||
if stat {
|
|
||||||
downloadUpdate(res)
|
|
||||||
updated = true
|
|
||||||
} else {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println("Failed Version File Info")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
if updated {
|
|
||||||
cmd := exec.Command("./LinuxPA")
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Start()
|
|
||||||
} else {
|
|
||||||
master = make(map[string][]app)
|
|
||||||
linmaster = make(map[string][]app)
|
|
||||||
gl.StartDriver(appMain)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func appMain(dri gxui.Driver) {
|
|
||||||
dr = dri
|
|
||||||
setup()
|
|
||||||
if darkTheme {
|
|
||||||
th = dark.CreateTheme(dr)
|
|
||||||
} else {
|
|
||||||
th = light.CreateTheme(dr)
|
|
||||||
}
|
|
||||||
th = dark.CreateTheme(dr)
|
|
||||||
ui()
|
|
||||||
}
|
|
||||||
|
|
||||||
func contains(arr []string, str string) bool {
|
|
||||||
for _, v := range arr {
|
|
||||||
if v == str {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"image"
|
|
||||||
"image/draw"
|
|
||||||
_ "image/png"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/nelsam/gxui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setup() {
|
|
||||||
PortableAppsFold, err := os.Open("PortableApps")
|
|
||||||
if PAStat, _ := PortableAppsFold.Stat(); err != nil || !PAStat.IsDir() {
|
|
||||||
os.Mkdir("PortableApps", 0777)
|
|
||||||
PortableAppsFold, err = os.Open("PortableApps")
|
|
||||||
if err != nil {
|
|
||||||
panic("Can't find PortableApps folder and can't create one!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err = os.Open("PortableApps/LinuxPACom"); err != nil {
|
|
||||||
os.Mkdir("PortableApps/LinuxPACom", 0777)
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
_, err = os.Open("PortableApps/LinuxPACom/common.sh")
|
|
||||||
if err == nil {
|
|
||||||
comEnbld = true
|
|
||||||
}
|
|
||||||
fi, err := os.Open("PortableApps/LinuxPACom/Info.ini")
|
|
||||||
if err != nil {
|
|
||||||
fi, err = os.Create("PortableApps/LinuxPACom/Info.ini")
|
|
||||||
if err == nil {
|
|
||||||
wrt := bufio.NewWriter(fi)
|
|
||||||
wrt.WriteString(defIni)
|
|
||||||
wrt.Flush()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
rdr := bufio.NewReader(fi)
|
|
||||||
for err != nil {
|
|
||||||
ln, _, error := rdr.ReadLine()
|
|
||||||
err = error
|
|
||||||
str := string(ln)
|
|
||||||
if strings.HasPrefix(str, "theme=") {
|
|
||||||
str = strings.TrimPrefix(str, "theme=")
|
|
||||||
if str == "lt" {
|
|
||||||
darkTheme = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PAFolds, _ := PortableAppsFold.Readdirnames(-1)
|
|
||||||
sort.Strings(PAFolds)
|
|
||||||
for _, v := range PAFolds {
|
|
||||||
fold, _ := os.Open("PortableApps/" + v)
|
|
||||||
if stat, _ := fold.Stat(); stat.IsDir() && stat.Name() != "PortableApps.com" && stat.Name() != "LinuxPACom" {
|
|
||||||
ap := processApp("PortableApps/" + v)
|
|
||||||
if !reflect.DeepEqual(ap, app{}) {
|
|
||||||
if _, ok := master[ap.cat]; !ok {
|
|
||||||
cats = append(cats, ap.cat)
|
|
||||||
sort.Strings(cats)
|
|
||||||
}
|
|
||||||
if len(ap.lin) != 0 {
|
|
||||||
if _, ok := linmaster[ap.cat]; !ok {
|
|
||||||
lin = append(lin, ap.cat)
|
|
||||||
sort.Strings(lin)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
master[ap.cat] = append(master[ap.cat], ap)
|
|
||||||
if len(ap.lin) != 0 {
|
|
||||||
linmaster[ap.cat] = append(linmaster[ap.cat], ap)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func processApp(fold string) (out app) {
|
|
||||||
wd, _ := os.Getwd()
|
|
||||||
out.dir = wd + "/" + fold
|
|
||||||
out.ini = findInfo(fold)
|
|
||||||
if out.ini != nil {
|
|
||||||
out.name = getName(out.ini)
|
|
||||||
out.ini = findInfo(fold)
|
|
||||||
out.cat = getCat(out.ini)
|
|
||||||
out.ini = findInfo(fold)
|
|
||||||
}
|
|
||||||
if out.name == "" {
|
|
||||||
out.name = strings.TrimPrefix(fold, "PortableApps/")
|
|
||||||
}
|
|
||||||
if out.cat == "" {
|
|
||||||
out.cat = "Other"
|
|
||||||
}
|
|
||||||
out.icon = getIcon(fold)
|
|
||||||
folder, _ := os.Open(fold)
|
|
||||||
fis, _ := folder.Readdirnames(-1)
|
|
||||||
for _, v := range fis {
|
|
||||||
tmp, _ := os.Open(fold + "/" + v)
|
|
||||||
if stat, _ := tmp.Stat(); stat.IsDir() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(strings.ToLower(v), ".appimage") {
|
|
||||||
out.appimg = append(out.appimg, v)
|
|
||||||
out.ex = append(out.ex, v)
|
|
||||||
out.lin = append(out.lin, v)
|
|
||||||
} else if strings.HasSuffix(strings.ToLower(v), ".exe") {
|
|
||||||
out.ex = append(out.ex, v)
|
|
||||||
} else {
|
|
||||||
btys := make([]byte, 4)
|
|
||||||
rdr := bufio.NewReader(tmp)
|
|
||||||
rdr.Read(btys)
|
|
||||||
if (strings.Contains(strings.ToLower(string(btys)), "elf") && !strings.HasSuffix(strings.ToLower(v), ".so") && !strings.Contains(v, ".so.")) || strings.HasPrefix(strings.ToLower(string(btys)), "#!") {
|
|
||||||
out.ex = append(out.ex, v)
|
|
||||||
out.lin = append(out.lin, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(out.ex) == 0 {
|
|
||||||
return app{}
|
|
||||||
}
|
|
||||||
if len(out.lin) == 0 {
|
|
||||||
out.name += " (Wine)"
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCat(ini *os.File) string {
|
|
||||||
rdr := bufio.NewReader(ini)
|
|
||||||
var ret string
|
|
||||||
for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() {
|
|
||||||
if strings.HasPrefix(string(line), "Category=") {
|
|
||||||
ret = strings.TrimPrefix(string(line), "Category=")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rdr.Reset(ini)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func getName(ini *os.File) string {
|
|
||||||
rdr := bufio.NewReader(ini)
|
|
||||||
var ret string
|
|
||||||
for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() {
|
|
||||||
if strings.HasPrefix(string(line), "Name=") {
|
|
||||||
ret = strings.TrimPrefix(string(line), "Name=")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rdr.Reset(ini)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func getIcon(fold string) gxui.Texture {
|
|
||||||
var pic *os.File
|
|
||||||
if folder, err := os.Open(fold + "/App/AppInfo"); err == nil {
|
|
||||||
fis, _ := folder.Readdir(-1)
|
|
||||||
var pics []string
|
|
||||||
for _, v := range fis {
|
|
||||||
if !v.IsDir() && strings.HasSuffix(strings.ToLower(v.Name()), ".png") && strings.HasPrefix(strings.ToLower(v.Name()), "appicon_") {
|
|
||||||
pics = append(pics, v.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Strings(pics)
|
|
||||||
if len(pics) > 1 {
|
|
||||||
var ind int
|
|
||||||
if !contains(pics, "appicon_32.png") {
|
|
||||||
ind = len(pics) - 1
|
|
||||||
} else {
|
|
||||||
ind = sort.SearchStrings(pics, "appicon_32.png")
|
|
||||||
}
|
|
||||||
pic, _ = os.Open(fold + "/App/AppInfo/" + pics[ind])
|
|
||||||
}
|
|
||||||
} else if fi, err := os.Open(fold + "/appicon.png"); err == nil {
|
|
||||||
pic = fi
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
img, _, err := image.Decode(pic)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
rgba := image.NewRGBA(img.Bounds())
|
|
||||||
draw.Draw(rgba, img.Bounds(), img, image.ZP, draw.Src)
|
|
||||||
ret := dr.CreateTexture(rgba, 1)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func findInfo(fold string) *os.File {
|
|
||||||
tmp, err := os.Open(fold + "/App/AppInfo")
|
|
||||||
if err == nil {
|
|
||||||
fis, _ := tmp.Readdirnames(-1)
|
|
||||||
for _, v := range fis {
|
|
||||||
if strings.ToLower(v) == "appinfo.ini" {
|
|
||||||
tmp, _ := os.Open(fold + "/App/AppInfo/" + v)
|
|
||||||
return tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fi, err := os.Open(fold + "/appinfo.ini"); err == nil {
|
|
||||||
return fi
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nelsam/gxui"
|
|
||||||
"github.com/nelsam/gxui/math"
|
|
||||||
)
|
|
||||||
|
|
||||||
//StrList TODO
|
|
||||||
type StrList struct {
|
|
||||||
gxui.AdapterBase
|
|
||||||
strs []string
|
|
||||||
}
|
|
||||||
|
|
||||||
//AddString TODO
|
|
||||||
func (s *StrList) AddString(add string) {
|
|
||||||
s.strs = append(s.strs, add)
|
|
||||||
s.DataChanged(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove TODO
|
|
||||||
func (s *StrList) Remove(index int) {
|
|
||||||
s.strs = append(s.strs[:index], s.strs[index+1:]...)
|
|
||||||
s.DataChanged(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
//SetStrings TODO
|
|
||||||
func (s *StrList) SetStrings(strs []string) {
|
|
||||||
s.strs = strs
|
|
||||||
s.DataChanged(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Count TODO
|
|
||||||
func (s *StrList) Count() int {
|
|
||||||
return len(s.strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
//ItemAt TODO
|
|
||||||
func (s *StrList) ItemAt(index int) gxui.AdapterItem {
|
|
||||||
return s.strs[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
//ItemIndex TODO
|
|
||||||
func (s *StrList) ItemIndex(item gxui.AdapterItem) int {
|
|
||||||
for i, v := range s.strs {
|
|
||||||
if v == item {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create TODO
|
|
||||||
func (s *StrList) Create(th gxui.Theme, index int) gxui.Control {
|
|
||||||
box := th.CreateLinearLayout()
|
|
||||||
box.SetDirection(gxui.LeftToRight)
|
|
||||||
lbl := th.CreateLabel()
|
|
||||||
lbl.SetText(s.strs[index])
|
|
||||||
box.AddChild(lbl)
|
|
||||||
return box
|
|
||||||
}
|
|
||||||
|
|
||||||
//Size TODO
|
|
||||||
func (s *StrList) Size(gxui.Theme) math.Size {
|
|
||||||
return math.Size{W: math.MaxSize.W, H: 20}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/nelsam/gxui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ui() {
|
|
||||||
catListAdap := &StrList{}
|
|
||||||
appListAdap := &catAdap{}
|
|
||||||
catListAdap.SetStrings(lin)
|
|
||||||
win := th.CreateWindow(500, 500, "LinuxPA")
|
|
||||||
top := th.CreateLinearLayout()
|
|
||||||
top.SetDirection(gxui.BottomToTop)
|
|
||||||
splBox := th.CreateLinearLayout()
|
|
||||||
spl := th.CreateSplitterLayout()
|
|
||||||
spl.SetOrientation(gxui.Horizontal)
|
|
||||||
catList := th.CreateList()
|
|
||||||
catList.SetAdapter(catListAdap)
|
|
||||||
catList.OnSelectionChanged(func(it gxui.AdapterItem) {
|
|
||||||
appListAdap.setCat(it.(string))
|
|
||||||
})
|
|
||||||
appList := th.CreateTree()
|
|
||||||
appList.SetAdapter(appListAdap)
|
|
||||||
spl.AddChild(catList)
|
|
||||||
spl.AddChild(appList)
|
|
||||||
splBox.AddChild(spl)
|
|
||||||
butBox := th.CreateLinearLayout()
|
|
||||||
butBox.SetDirection(gxui.LeftToRight)
|
|
||||||
if _, err := exec.LookPath("wine"); err == nil {
|
|
||||||
wineBut := th.CreateButton()
|
|
||||||
wineBut.SetType(gxui.ToggleButton)
|
|
||||||
wineBut.SetChecked(wine)
|
|
||||||
wineBut.SetText("Show Windows Apps")
|
|
||||||
wineBut.OnClick(func(gxui.MouseEvent) {
|
|
||||||
wine = wineBut.IsChecked()
|
|
||||||
appListAdap.refresh()
|
|
||||||
if wineBut.IsChecked() {
|
|
||||||
catListAdap.SetStrings(cats)
|
|
||||||
wineBut.SetText("Hide Windows Apps")
|
|
||||||
} else {
|
|
||||||
catListAdap.SetStrings(lin)
|
|
||||||
wineBut.SetText("Show Windows Apps")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
_, err := os.Open("Start.exe")
|
|
||||||
if err == nil {
|
|
||||||
pa := th.CreateButton()
|
|
||||||
pa.SetText("Open PortableApps Launcher")
|
|
||||||
pa.OnClick(func(gxui.MouseEvent) {
|
|
||||||
cmd := exec.Command("wine", "Start.exe")
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
cmd.Start()
|
|
||||||
})
|
|
||||||
butBox.AddChild(pa)
|
|
||||||
}
|
|
||||||
butBox.AddChild(wineBut)
|
|
||||||
}
|
|
||||||
top.AddChild(butBox)
|
|
||||||
top.AddChild(splBox)
|
|
||||||
win.AddChild(top)
|
|
||||||
win.OnClose(dr.Terminate)
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -10,20 +9,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "2.1.2.1"
|
version = "2.1.5.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
master map[string][]app
|
master map[string][]app
|
||||||
linmaster map[string][]app
|
linmaster map[string][]app
|
||||||
cats []string
|
cats []string
|
||||||
lin []string
|
lin []string
|
||||||
wine bool
|
comEnbld bool
|
||||||
comEnbld bool
|
populated bool
|
||||||
wineAvail bool
|
|
||||||
portableHide bool
|
|
||||||
versionNewest = true
|
|
||||||
paDirs = true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -56,55 +51,6 @@ func uiStart(forced bool) {
|
|||||||
gtk.Main()
|
gtk.Main()
|
||||||
}
|
}
|
||||||
|
|
||||||
func savePrefs() {
|
|
||||||
os.Remove("PortableApps/LinuxPACom/Prefs.gob")
|
|
||||||
fil, err := os.Create("PortableApps/LinuxPACom/Prefs.gob")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
enc := gob.NewEncoder(fil)
|
|
||||||
err = enc.Encode(wine)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = enc.Encode(portableHide)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = enc.Encode(versionNewest)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = enc.Encode(paDirs)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadPrefs() {
|
|
||||||
fil, err := os.Open("PortableApps/LinuxPACom/Prefs.gob")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dec := gob.NewDecoder(fil)
|
|
||||||
err = dec.Decode(&wine)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = dec.Decode(&portableHide)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = dec.Decode(&versionNewest)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = dec.Decode(&paDirs)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func contains(arr []string, str string) bool {
|
func contains(arr []string, str string) bool {
|
||||||
for _, v := range arr {
|
for _, v := range arr {
|
||||||
if v == str {
|
if v == str {
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/gob"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
wine bool
|
||||||
|
wineAvail bool
|
||||||
|
portableHide bool
|
||||||
|
betaUpdate bool
|
||||||
|
versionNewest = true
|
||||||
|
paDirs = true
|
||||||
|
)
|
||||||
|
|
||||||
|
func savePrefs() {
|
||||||
|
os.Remove("PortableApps/LinuxPACom/Prefs.gob")
|
||||||
|
fil, err := os.Create("PortableApps/LinuxPACom/Prefs.gob")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enc := gob.NewEncoder(fil)
|
||||||
|
err = enc.Encode(wine)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = enc.Encode(portableHide)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = enc.Encode(versionNewest)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = enc.Encode(paDirs)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = enc.Encode(betaUpdate)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPrefs() {
|
||||||
|
fil, err := os.Open("PortableApps/LinuxPACom/Prefs.gob")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dec := gob.NewDecoder(fil)
|
||||||
|
err = dec.Decode(&wine)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = dec.Decode(&portableHide)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = dec.Decode(&versionNewest)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = dec.Decode(&paDirs)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = dec.Decode(&betaUpdate)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ func settingsUI(parent *gtk.Window, onExit func()) {
|
|||||||
win.SetDefaultSize(600, 300)
|
win.SetDefaultSize(600, 300)
|
||||||
win.SetPosition(gtk.WIN_POS_CENTER_ON_PARENT)
|
win.SetPosition(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||||
win.Connect("destroy", func() {
|
win.Connect("destroy", func() {
|
||||||
|
savePrefs()
|
||||||
parent.SetSensitive(true)
|
parent.SetSensitive(true)
|
||||||
onExit()
|
onExit()
|
||||||
})
|
})
|
||||||
@@ -93,12 +94,14 @@ func settingsUI(parent *gtk.Window, onExit func()) {
|
|||||||
paDirsCheck.Connect("toggled", func() {
|
paDirsCheck.Connect("toggled", func() {
|
||||||
paDirs = paDirsCheck.GetActive()
|
paDirs = paDirsCheck.GetActive()
|
||||||
})
|
})
|
||||||
|
betaCheck, _ := gtk.CheckButtonNewWithLabel("Update to beta releases")
|
||||||
gnrl.Add(wineLbl)
|
gnrl.Add(wineLbl)
|
||||||
gnrl.Add(dlWine)
|
gnrl.Add(dlWine)
|
||||||
gnrl.Add(pthdCheck)
|
gnrl.Add(pthdCheck)
|
||||||
gnrl.Add(wineCheck)
|
gnrl.Add(wineCheck)
|
||||||
gnrl.Add(versCheck)
|
gnrl.Add(versCheck)
|
||||||
gnrl.Add(paDirsCheck)
|
gnrl.Add(paDirsCheck)
|
||||||
|
gnrl.Add(betaCheck)
|
||||||
ntbk.AppendPage(gnrl, getLabel("General"))
|
ntbk.AppendPage(gnrl, getLabel("General"))
|
||||||
com, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5)
|
com, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5)
|
||||||
com.SetMarginStart(10)
|
com.SetMarginStart(10)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
goappimage "github.com/CalebQ42/GoAppImage"
|
||||||
"github.com/gotk3/gotk3/gdk"
|
"github.com/gotk3/gotk3/gdk"
|
||||||
"github.com/gotk3/gotk3/gtk"
|
"github.com/gotk3/gotk3/gtk"
|
||||||
)
|
)
|
||||||
@@ -64,35 +65,21 @@ func setup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
populated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func processApp(fold string) (out app) {
|
func processApp(fold string) (out app) {
|
||||||
wd, _ := os.Getwd()
|
wd, _ := os.Getwd()
|
||||||
out.dir = wd + "/" + fold
|
out.dir = wd + "/" + fold
|
||||||
out.ini = findInfo(fold)
|
|
||||||
if out.ini != nil {
|
|
||||||
out.name = getName(out.ini)
|
|
||||||
out.ini = findInfo(fold)
|
|
||||||
out.cat = getCat(out.ini)
|
|
||||||
out.ini = findInfo(fold)
|
|
||||||
}
|
|
||||||
if out.name == "" {
|
|
||||||
out.name = strings.TrimPrefix(fold, "PortableApps/")
|
|
||||||
}
|
|
||||||
if out.cat == "" {
|
|
||||||
out.cat = "Other"
|
|
||||||
}
|
|
||||||
if portableHide {
|
|
||||||
out.name = strings.TrimSuffix(out.name, "Portable")
|
|
||||||
}
|
|
||||||
out.icon = getIcon(fold)
|
|
||||||
folder, _ := os.Open(fold)
|
folder, _ := os.Open(fold)
|
||||||
fis, _ := folder.Readdirnames(-1)
|
fis, _ := folder.Readdirnames(-1)
|
||||||
for _, v := range fis {
|
for _, v := range fis {
|
||||||
tmp, _ := os.Open(fold + "/" + v)
|
tmp, _ := os.Open(fold + "/" + v)
|
||||||
if stat, _ := tmp.Stat(); stat.IsDir() {
|
stat, _ := tmp.Stat()
|
||||||
|
if stat.IsDir() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
//TODO: check permission to see if it has exec permission
|
||||||
if strings.HasSuffix(strings.ToLower(v), ".appimage") {
|
if strings.HasSuffix(strings.ToLower(v), ".appimage") {
|
||||||
out.appimg = append(out.appimg, v)
|
out.appimg = append(out.appimg, v)
|
||||||
out.ex = append(out.ex, v)
|
out.ex = append(out.ex, v)
|
||||||
@@ -114,7 +101,90 @@ func processApp(fold string) (out app) {
|
|||||||
}
|
}
|
||||||
if len(out.lin) == 0 {
|
if len(out.lin) == 0 {
|
||||||
out.name += " (Wine)"
|
out.name += " (Wine)"
|
||||||
|
out.wine = true
|
||||||
}
|
}
|
||||||
|
out.icon = getIcon(fold)
|
||||||
|
out.ini = findInfo(fold)
|
||||||
|
if out.ini != nil {
|
||||||
|
out.name = getName(out.ini)
|
||||||
|
out.cat = getCat(out.ini)
|
||||||
|
}
|
||||||
|
if len(out.appimg) > 0 && out.name == "" && out.cat == "" && out.icon == nil {
|
||||||
|
os.Mkdir(out.dir+"/.appimageconfig", 0777)
|
||||||
|
ai := goappimage.NewAppImage(out.dir + "/" + out.appimg[0])
|
||||||
|
fil, err := os.Open(out.dir + "/.appimageconfig/the.md5")
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
ai.ExtractFile("*.desktop", out.dir+"/.appimageconfig/", false)
|
||||||
|
appimageconfig, _ := os.Open(out.dir + "/.appimageconfig")
|
||||||
|
appdirs, _ := appimageconfig.Readdirnames(-1)
|
||||||
|
for _, dirs := range appdirs {
|
||||||
|
desktopFil, _ := os.Open(out.dir + "/.appimageconfig/" + dirs)
|
||||||
|
if stat, _ := desktopFil.Stat(); strings.HasSuffix(dirs, ".desktop") && !stat.IsDir() {
|
||||||
|
os.Rename(out.dir+"/.appimageconfig/"+dirs, out.dir+"/.appimageconfig/the.desktop")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
desk, _ := os.Open(out.dir + "/.appimageconfig/the.desktop")
|
||||||
|
name, cat, icon := extractDesktopInfo(desk)
|
||||||
|
if out.name == "" {
|
||||||
|
out.name = name
|
||||||
|
}
|
||||||
|
if out.cat == "" {
|
||||||
|
out.cat = cat
|
||||||
|
}
|
||||||
|
if out.icon == nil {
|
||||||
|
it, _ := gtk.IconThemeGetDefault()
|
||||||
|
out.icon, err = it.LoadIcon(icon, 64, gtk.ICON_LOOKUP_GENERIC_FALLBACK)
|
||||||
|
}
|
||||||
|
fil, _ = os.Create(out.dir + "/.appimageconfig/the.md5")
|
||||||
|
wrtr := bufio.NewWriter(fil)
|
||||||
|
wrtr.WriteString(ai.Md5)
|
||||||
|
wrtr.Flush()
|
||||||
|
} else {
|
||||||
|
rdr := bufio.NewReader(fil)
|
||||||
|
filMd, _, _ := rdr.ReadLine()
|
||||||
|
oldMd := string(filMd)
|
||||||
|
if oldMd != ai.Md5 {
|
||||||
|
ai.ExtractFile("*.desktop", out.dir+"/.appimageconfig/", false)
|
||||||
|
appimageconfig, _ := os.Open(out.dir + "/.appimageconfig")
|
||||||
|
appdirs, _ := appimageconfig.Readdirnames(-1)
|
||||||
|
for _, dirs := range appdirs {
|
||||||
|
desktopFil, _ := os.Open(out.dir + "/.appimageconfig/" + dirs)
|
||||||
|
if stat, _ := desktopFil.Stat(); strings.HasSuffix(dirs, ".desktop") && !stat.IsDir() {
|
||||||
|
os.Rename(out.dir+"/.appimageconfig/"+dirs, out.dir+"/.appimageconfig/the.desktop")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.Remove(out.dir + "/.appimageconfig/the.md5")
|
||||||
|
fil, _ = os.Create(out.dir + "/.appimageconfig/the.md5")
|
||||||
|
wrtr := bufio.NewWriter(fil)
|
||||||
|
wrtr.WriteString(ai.Md5)
|
||||||
|
wrtr.Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
desk, _ := os.Open(out.dir + "/.appimageconfig/the.desktop")
|
||||||
|
name, cat, icon := extractDesktopInfo(desk)
|
||||||
|
if out.name == "" {
|
||||||
|
out.name = name
|
||||||
|
}
|
||||||
|
if out.cat == "" {
|
||||||
|
out.cat = cat
|
||||||
|
}
|
||||||
|
if out.icon == nil {
|
||||||
|
it, _ := gtk.IconThemeGetDefault()
|
||||||
|
out.icon, err = it.LoadIcon(icon, 32, gtk.ICON_LOOKUP_GENERIC_FALLBACK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if out.name == "" {
|
||||||
|
out.name = strings.TrimPrefix(fold, "PortableApps/")
|
||||||
|
}
|
||||||
|
if out.cat == "" {
|
||||||
|
out.cat = "Other"
|
||||||
|
}
|
||||||
|
if portableHide {
|
||||||
|
out.name = strings.TrimSuffix(out.name, "Portable")
|
||||||
|
}
|
||||||
|
out.name = strings.TrimSpace(out.name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +203,31 @@ func getCat(ini *os.File) string {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractDesktopInfo(desk *os.File) (name, category, iconName string) {
|
||||||
|
rdr := bufio.NewReader(desk)
|
||||||
|
var nameGot, catGot, iconGot bool
|
||||||
|
for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() {
|
||||||
|
ln := string(line)
|
||||||
|
if !nameGot && strings.HasPrefix(ln, "Name=") {
|
||||||
|
name = strings.TrimPrefix(ln, "Name=")
|
||||||
|
nameGot = true
|
||||||
|
} else if !catGot && strings.HasPrefix(ln, "Categories=") {
|
||||||
|
cats := strings.Split(strings.TrimPrefix(ln, "Categories="), ";")
|
||||||
|
if len(cats) > 0 {
|
||||||
|
category = cats[0]
|
||||||
|
}
|
||||||
|
catGot = true
|
||||||
|
} else if !iconGot && strings.HasPrefix(ln, "Icon=") {
|
||||||
|
iconName = strings.TrimPrefix(ln, "Icon=")
|
||||||
|
iconGot = true
|
||||||
|
}
|
||||||
|
if nameGot && catGot && iconGot {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func getName(ini *os.File) string {
|
func getName(ini *os.File) string {
|
||||||
rdr := bufio.NewReader(ini)
|
rdr := bufio.NewReader(ini)
|
||||||
var ret string
|
var ret string
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/CalebQ42/LinuxPA/appimg"
|
|
||||||
"github.com/gotk3/gotk3/glib"
|
"github.com/gotk3/gotk3/glib"
|
||||||
"github.com/gotk3/gotk3/gtk"
|
"github.com/gotk3/gotk3/gtk"
|
||||||
|
"github.com/pkg/browser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ui(win *gtk.Window) {
|
func ui(win *gtk.Window) {
|
||||||
@@ -140,22 +140,8 @@ func ui(win *gtk.Window) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
dnl.Connect("clicked", func() {
|
dnl.Connect("clicked", func() {
|
||||||
appimg.ShowUI(versionNewest, func() {
|
//TODO: detect if a webbrowser app is available and use that instead
|
||||||
master = make(map[string][]app)
|
browser.OpenURL("https://appimage.github.io/apps/")
|
||||||
linmaster = make(map[string][]app)
|
|
||||||
cats = make([]string, 0)
|
|
||||||
lin = make([]string, 0)
|
|
||||||
setup()
|
|
||||||
store.Clear()
|
|
||||||
for i := range ls {
|
|
||||||
catList.Remove(catList.GetRowAtIndex(len(ls) - i - 1))
|
|
||||||
}
|
|
||||||
ls = getCatRows()
|
|
||||||
for i, v := range ls {
|
|
||||||
catList.Insert(v, i)
|
|
||||||
}
|
|
||||||
catList.ShowAll()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
settings.Connect("clicked", func() {
|
settings.Connect("clicked", func() {
|
||||||
settingsUI(win, func() {
|
settingsUI(win, func() {
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
versionURL = "https://www.dropbox.com/s/a0xizzo0a4vsfqt/Version?dl=1"
|
versionURL = "https://www.dropbox.com/s/a0xizzo0a4vsfqt/Version?dl=1"
|
||||||
downloadURL = "https://github.com/CalebQ42/LinuxPA/releases/download/vXXX/LinuxPA"
|
downloadURL = "https://github.com/CalebQ42/LinuxPA/releases/download/vXXX/LinuxPA"
|
||||||
changelogURL = "https://www.dropbox.com/s/nmbk318er5kej5h/Changelog?dl=1"
|
changelogURL = "https://www.dropbox.com/s/nmbk318er5kej5h/Changelog?dl=1"
|
||||||
|
changelogBetaURL = "https://www.dropbox.com/s/m8mo2o3nsvfqbfx/ChangelogBeta?dl=1"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Thanks to https://www.socketloop.com/tutorials/golang-download-file-example
|
//Thanks to https://www.socketloop.com/tutorials/golang-download-file-example
|
||||||
@@ -47,14 +48,17 @@ func versionDL() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVersionFileInfo() string {
|
func getVersionFileInfo() (stable string, beta string) {
|
||||||
fil, err := os.Open("PortableApps/LinuxPACom/Version")
|
fil, err := os.Open("PortableApps/LinuxPACom/Version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "Error!"
|
return "Error!", ""
|
||||||
}
|
}
|
||||||
rdr := bufio.NewReader(fil)
|
rdr := bufio.NewReader(fil)
|
||||||
out, _, _ := rdr.ReadLine()
|
out, _, _ := rdr.ReadLine()
|
||||||
return string(out)
|
stable = string(out)
|
||||||
|
out, _, _ = rdr.ReadLine()
|
||||||
|
beta = string(out)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func changelogDL() (bool, error) {
|
func changelogDL() (bool, error) {
|
||||||
@@ -69,7 +73,12 @@ func changelogDL() (bool, error) {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
response, err := check.Get(changelogURL)
|
var response *http.Response
|
||||||
|
if betaUpdate {
|
||||||
|
response, err = check.Get(changelogBetaURL)
|
||||||
|
} else {
|
||||||
|
response, err = check.Get(changelogURL)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -89,7 +98,11 @@ func getChangelog() string {
|
|||||||
return string(out)
|
return string(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkForUpdate(new string) (bool, error) {
|
func checkForUpdate(stable, beta string) (bool, error) {
|
||||||
|
new := stable
|
||||||
|
if betaUpdate {
|
||||||
|
new = beta
|
||||||
|
}
|
||||||
curSlice := strings.Split(version, ".")
|
curSlice := strings.Split(version, ".")
|
||||||
newSlice := strings.Split(new, ".")
|
newSlice := strings.Split(new, ".")
|
||||||
curNums := make([]int, 4)
|
curNums := make([]int, 4)
|
||||||
@@ -148,9 +161,9 @@ func downloadUpdate(newVersion string) (bool, error) {
|
|||||||
func update(win *gtk.Window, forced bool) {
|
func update(win *gtk.Window, forced bool) {
|
||||||
stat, err := versionDL()
|
stat, err := versionDL()
|
||||||
if stat {
|
if stat {
|
||||||
res := getVersionFileInfo()
|
stable, beta := getVersionFileInfo()
|
||||||
if res != "Error!" {
|
if stable != "Error!" {
|
||||||
stat, err = checkForUpdate(res)
|
stat, err = checkForUpdate(stable, beta)
|
||||||
if stat || forced {
|
if stat || forced {
|
||||||
stat, err = changelogDL()
|
stat, err = changelogDL()
|
||||||
if stat {
|
if stat {
|
||||||
@@ -222,11 +235,15 @@ func actuallyUpdate(win *gtk.Window, forced bool) {
|
|||||||
defer updateWin.Close()
|
defer updateWin.Close()
|
||||||
stat, err := versionDL()
|
stat, err := versionDL()
|
||||||
if stat {
|
if stat {
|
||||||
res := getVersionFileInfo()
|
stable, beta := getVersionFileInfo()
|
||||||
if res != "Error!" {
|
if stable != "Error!" {
|
||||||
stat, err = checkForUpdate(res)
|
stat, err = checkForUpdate(stable, beta)
|
||||||
if stat || forced {
|
if stat || forced {
|
||||||
downloadUpdate(res)
|
if betaUpdate {
|
||||||
|
downloadUpdate(beta)
|
||||||
|
} else {
|
||||||
|
downloadUpdate(stable)
|
||||||
|
}
|
||||||
win.Close()
|
win.Close()
|
||||||
cmd := exec.Command("./LinuxPA")
|
cmd := exec.Command("./LinuxPA")
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gotk3/gotk3/gtk"
|
"github.com/gotk3/gotk3/gtk"
|
||||||
"github.com/mholt/archiver"
|
"github.com/mholt/archiver/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
wineURL = "https://www.playonlinux.com/wine/binaries/linux-amd64/PlayOnLinux-wine-2.5-linux-amd64.pol"
|
wineURL = "https://www.playonlinux.com/wine/binaries/phoenicis/staging-linux-amd64/PlayOnLinux-wine-5.20-staging-linux-amd64.tar.gz"
|
||||||
)
|
)
|
||||||
|
|
||||||
func downloadWine(parent *gtk.Window, cb chan bool) {
|
func downloadWine(parent *gtk.Window, cb chan bool) {
|
||||||
@@ -40,7 +40,7 @@ func downloadWine(parent *gtk.Window, cb chan bool) {
|
|||||||
win.Show()
|
win.Show()
|
||||||
go func(win *gtk.Window, txt *gtk.Label) {
|
go func(win *gtk.Window, txt *gtk.Label) {
|
||||||
defer win.Close()
|
defer win.Close()
|
||||||
wineTar, err := os.Create("PortableApps/LinuxPACom/wine2.5.tar.bz2")
|
wineTar, err := os.Create("PortableApps/LinuxPACom/wine5.20.tar.bz2")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
cb <- false
|
cb <- false
|
||||||
@@ -68,7 +68,7 @@ func downloadWine(parent *gtk.Window, cb chan bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
txt.SetText("Extracting Wine")
|
txt.SetText("Extracting Wine")
|
||||||
err = archiver.TarBz2.Open("PortableApps/LinuxPACom/wine2.5.tar.bz2", "PortableApps/LinuxPACom/Wine")
|
err = archiver.DefaultTarBz2.Unarchive("PortableApps/LinuxPACom/wine2.5.tar.bz2", "PortableApps/LinuxPACom/Wine")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
cb <- false
|
cb <- false
|
||||||
|
|||||||
Reference in New Issue
Block a user