package app import ( "fmt" "image/png" "log" "net/url" "os" "path/filepath" "strings" "text/template" "time" ) // Launcher is the source code template for a desktop launcher. const Launcher = `[Desktop Entry] Version=1.0 Name={{ .Name }} GenericName={{ .Name }} Comment=Progressive Web App Exec={{ .Exec }} Icon={{ .Icon }} Terminal=false Type=Application StartupNotify=true Categories=Network; ` // Vars for the launcher template. type Vars struct { Name string Exec string Icon string } // Install the launcher and icon. func Install(p Parameters) { var ( HOME = os.Getenv("HOME") basename = UID(p) ) if HOME == "" { panic("No $HOME variable found for current user!") } // Ensure directories exist. for _, path := range []string{ filepath.Join(HOME, ".local", "share", "applications"), filepath.Join(HOME, ".config", "pwa-launcher"), } { err := os.MkdirAll(path, 0755) if err != nil { log.Fatalf("Failed to mkdir %s: %s", path, err) } } // Write the PNG image. var iconPath = filepath.Join(HOME, ".config", "pwa-launcher", basename+".png") log.Printf("Write icon to: %s", iconPath) icoFH, err := os.Create(iconPath) if err != nil { panic(err) } defer icoFH.Close() if err := png.Encode(icoFH, p.iconData); err != nil { panic(err) } // Write the desktop launcher. var launcherPath = filepath.Join(HOME, ".local", "share", "applications", basename+".desktop") log.Printf("Write launcher to: %s", launcherPath) fh, err := os.Create(launcherPath) if err != nil { panic(err) } defer fh.Close() t := template.Must(template.New("launcher").Parse(Launcher)) err = t.Execute(fh, Vars{ Name: p.Title, Exec: fmt.Sprintf(p.Exec, p.URL), Icon: iconPath, }) if err != nil { panic(err) } } // UID generates a unique name for the launcher and icon files. func UID(p Parameters) string { var name = "pwa-" uri, err := url.Parse(p.URL) if err == nil { name += strings.Replace(uri.Host, ":", "_", -1) + "-" } name += fmt.Sprintf("%d", time.Now().Unix()) return name }