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