1//go:build linux 2// +build linux 3 4package setup 5 6import ( 7 "errors" 8 "fmt" 9 "io/ioutil" 10 "log" 11 "os" 12 "os/exec" 13 "os/user" 14 "strings" 15) 16 17const DESKTOPFILE = ` 18[Desktop Entry] 19Type=Application 20Name=Local Link Scheme Handler 21Exec=%s %%u 22StartupNotify=false 23MimeType=%s; 24` 25 26// see https://unix.stackexchange.com/questions/497146/create-a-custom-url-protocol-handler 27func Install() error { 28 self, _ := os.Executable() 29 desktopFile := desktopFile() 30 schemeMimeType := fmt.Sprintf("x-scheme-handler/%s", PROTOCOL) 31 desktopEntry := strings.TrimLeft(fmt.Sprintf(DESKTOPFILE, self, schemeMimeType), "\n") 32 desktopFilePath, err1 := desktopFilePath() 33 if err1 != nil { 34 return err1 35 } 36 37 log.Print(desktopEntry) 38 err2 := ioutil.WriteFile(desktopFilePath, []byte(desktopEntry), 0644) 39 if err2 != nil { 40 return err2 41 } 42 43 out, err3 := exec.Command("xdg-mime", "default", desktopFile, schemeMimeType).CombinedOutput() 44 if err3 != nil { 45 46 return fmt.Errorf("Failed to execute xdg-mime command.\n%s\n%s", err3.Error(), out) 47 } 48 49 return nil 50} 51 52func Uninstall() error { 53 desktopFilePath, err0 := desktopFilePath() 54 if err0 != nil { 55 return err0 56 } 57 58 _, err1 := os.Stat(desktopFilePath) 59 if os.IsNotExist(err1) { 60 return errors.New("No handler found.") 61 } 62 63 err2 := os.Remove(desktopFilePath) 64 if err2 != nil { 65 return fmt.Errorf("Failed to remove desktop file.\n%s\n%s", desktopFilePath, err2.Error()) 66 } 67 return nil 68} 69 70func PreparePath(path string, isLetter bool) string { 71 if isLetter { 72 // we assume that the path is auto-mounted under /media/<letter> 73 path = strings.Replace(path, ":\\", "/", -1) 74 return "/media/" + path 75 } else { 76 return "smb:" + path 77 } 78} 79 80func Run(path string) error { 81 out, err := exec.Command("xdg-open", path).CombinedOutput() 82 if err != nil { 83 return fmt.Errorf("Failed to execute xdg-open command.\n%s\n%s", err.Error(), out) 84 } 85 86 return nil 87} 88 89func desktopFile() string { 90 return fmt.Sprintf("%s-handler.desktop", PROTOCOL) 91} 92 93func desktopFilePath() (string, error) { 94 usr, err := user.Current() 95 if err != nil { 96 return "", err 97 } 98 99 location := fmt.Sprintf("%s/.local/share/applications/%s", usr.HomeDir, desktopFile()) 100 return location, nil 101} 102