9e9bb82025
Added "Hide Portable from app names"
200 lines
5.1 KiB
Go
200 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
_ "image/png"
|
|
"os"
|
|
"os/exec"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/gotk3/gotk3/gdk"
|
|
"github.com/gotk3/gotk3/gtk"
|
|
)
|
|
|
|
func setup() {
|
|
loadPrefs()
|
|
if _, err := os.Open("PortableApps/LinuxPACom/Wine"); os.IsNotExist(err) {
|
|
if _, errd := exec.LookPath("wine"); errd == nil {
|
|
wineAvail = true
|
|
}
|
|
} else if err == nil {
|
|
wineAvail = true
|
|
}
|
|
if !wineAvail {
|
|
wine = false
|
|
}
|
|
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)
|
|
}
|
|
_, err = os.Open("PortableApps/LinuxPACom/common.sh")
|
|
if err == nil {
|
|
comEnbld = true
|
|
}
|
|
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"
|
|
}
|
|
if portableHide {
|
|
out.name = strings.TrimSuffix(out.name, "Portable")
|
|
}
|
|
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
|
|
} else if strings.HasPrefix(string(line), "category=") {
|
|
ret = strings.TrimPrefix(string(line), "category=")
|
|
}
|
|
}
|
|
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
|
|
} else if strings.HasPrefix(string(line), "name=") {
|
|
ret = strings.TrimPrefix(string(line), "name=")
|
|
break
|
|
}
|
|
}
|
|
rdr.Reset(ini)
|
|
return ret
|
|
}
|
|
|
|
func getIcon(fold string) *gdk.Pixbuf {
|
|
var pic string
|
|
if _, err := os.Open(fold + "/appicon.png"); err == nil {
|
|
pic = fold + "/appicon.png"
|
|
} else 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 = fold + "/App/AppInfo/" + pics[ind]
|
|
}
|
|
} else {
|
|
img, _ := gtk.ImageNewFromIconName("application-x-executable", gtk.ICON_SIZE_BUTTON)
|
|
buf := img.GetPixbuf()
|
|
return buf
|
|
}
|
|
img, _ := gtk.ImageNewFromFile(pic)
|
|
buf, _ := img.GetPixbuf().ScaleSimple(32, 32, gdk.INTERP_BILINEAR)
|
|
return buf
|
|
}
|
|
|
|
func findInfo(fold string) *os.File {
|
|
if fi, err := os.Open(fold + "/appinfo.ini"); err == nil {
|
|
return fi
|
|
}
|
|
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
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|