From 41f25418e8b30e7597e57ad5d091983a4733be8b Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Tue, 7 Jan 2020 21:22:44 +0000 Subject: [PATCH] Initial implementation for .desktop fuse fs --- dot-desktop-fuse/main.go | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 dot-desktop-fuse/main.go diff --git a/dot-desktop-fuse/main.go b/dot-desktop-fuse/main.go new file mode 100644 index 0000000..985068e --- /dev/null +++ b/dot-desktop-fuse/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "bytes" + "context" + "io/ioutil" + "log" + "os" + "os/signal" + "path/filepath" + "regexp" + "syscall" + + "github.com/hanwen/go-fuse/v2/fs" + "github.com/hanwen/go-fuse/v2/fuse" +) + +type ddf struct { + Path string + fs.Inode +} + +func (r *ddf) OnAdd(ctx context.Context) { + files, err := ioutil.ReadDir(r.Path) + if err != nil { + log.Fatal(err) + } + + for _, file := range files { + b, err := ioutil.ReadFile(filepath.Join(r.Path, file.Name())) + if err != nil { + log.Fatal(err) + } + + b = bytes.ReplaceAll(b, []byte("Actions="), []byte("Actions=appvm;")) + + raw := string(regexp.MustCompile("Exec=[a-zA-Z0-9]*").Find(b)) + + var app string + if len(raw) > 5 { + app = string(raw)[5:] + } else { + log.Println("Can't find Exec entry for", file.Name()) + continue + } + + b = append(b, []byte("\n[Desktop Action appvm]\n")...) + b = append(b, []byte("Name=Open in appvm\n")...) + b = append(b, []byte("Exec=appvm start "+app+"\n")...) + + ch := r.NewPersistentInode( + ctx, &fs.MemRegularFile{ + Data: b, + Attr: fuse.Attr{Mode: 0444}, + }, fs.StableAttr{}) + r.AddChild(file.Name(), ch, false) + } +} + +var _ = (fs.NodeOnAdder)((*ddf)(nil)) + +func setupSigintHandler(server *fuse.Server) { + c := make(chan os.Signal) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + server.Unmount() + os.Exit(1) + }() +} + +func main() { + const from = "/var/run/current-system/sw/share/applications/" + + to := filepath.Join(os.Getenv("HOME"), "/.local/share/applications") + os.MkdirAll(to, 0755) + + server, err := fs.Mount(to, &ddf{Path: from}, nil) + if err != nil { + log.Fatal(err) + } + setupSigintHandler(server) + server.Wait() +}