Files
LinuxPA/app.go
T
2024-09-28 06:28:54 -05:00

114 lines
2.1 KiB
Go

package main
import (
"bytes"
"log"
"os"
"path/filepath"
"slices"
"strings"
"github.com/probonopd/go-appimage/src/goappimage"
)
type ExeType byte
const (
Script = ExeType(iota + 1)
AppImage
ELF
Win
)
type Exe struct {
Filename string
Type ExeType
}
type App struct {
Name string
Execs []Exe
// Image []byte TODO
}
func ProcessAppImage(fil string) (*App, error) {
ai, err := goappimage.NewAppImage(fil)
if err != nil {
return nil, err
}
app := App{
Name: ai.Name,
// Image: ,
Execs: []Exe{
{
Filename: fil,
Type: AppImage,
},
},
}
return &app, nil
}
func ProcessDir(dir string) (*App, error) {
fils, err := os.ReadDir(dir)
if err != nil {
log.Printf("Unable to list files in %v: %v\n", dir, err)
return nil, err
}
app := App{
Name: filepath.Base(dir),
}
for _, f := range fils {
if f.IsDir() {
continue
}
var t ExeType
if strings.HasSuffix(strings.ToLower(f.Name()), ".exe") {
t = Win
} else {
fil, err := os.Open(filepath.Join(dir, f.Name()))
if err != nil {
log.Printf("Error opening %v: %v\n", filepath.Join(dir, f.Name()), err)
continue
}
startByts := make([]byte, 4)
_, err = fil.Read(startByts)
if err != nil {
log.Printf("Error reading starting bytes of %v: %v\n", filepath.Join(dir, f.Name()), err)
continue
}
if bytes.HasPrefix(startByts, []byte("#!")) {
t = Script
} else if bytes.Contains(bytes.ToLower(startByts), []byte("elf")) {
if strings.HasSuffix(strings.ToLower(f.Name()), ".so") || strings.Contains(strings.ToLower(f.Name()), ".so.") {
continue
}
if goappimage.IsAppImage(filepath.Join(dir, f.Name())) {
t = AppImage
} else {
t = ELF
}
}
}
if t != 0 {
app.Execs = append(app.Execs, Exe{
Filename: f.Name(),
Type: t,
})
}
}
if len(app.Execs) == 0 {
return nil, nil
}
slices.SortFunc(app.Execs, func(a, b Exe) int {
if a.Type > b.Type {
return 1
} else if a.Type < b.Type {
return -1
}
return strings.Compare(a.Filename, b.Filename)
})
//TODO: get "proper" name & icon, either from AppImage or PortableApps spec
return &app, nil
}