1package main
2
3import (
4	"flag"
5	"fmt"
6	fyne "fyne.io/fyne/v2"
7	"fyne.io/fyne/v2/app"
8	"fyne.io/fyne/v2/container"
9	"fyne.io/fyne/v2/dialog"
10	"fyne.io/fyne/v2/layout"
11	"fyne.io/fyne/v2/widget"
12	"github.com/apenwarr/fixconsole"
13	"github.com/cosmocode/golocal/i18n"
14	setup "github.com/cosmocode/golocal/setup"
15	"log"
16	"net/url"
17	"os"
18	"regexp"
19	"strings"
20)
21
22func main() {
23	_ = fixconsole.FixConsoleIfNeeded()
24	log.SetOutput(os.Stdout)
25	fmt.Println()
26
27	flag.Usage = usage
28	flagInstall := flag.Bool("install", false, "Install the protocol handler")
29	flagUninstall := flag.Bool("uninstall", false, "Uninstall the protocol handler")
30
31	// Parse flags and check for errors
32	if err := flag.CommandLine.Parse(os.Args[1:]); err != nil {
33		log.Fatalf("Error: %s", err)
34	}
35
36	// Check for unknown flags
37	if flag.NArg() > 0 && strings.HasPrefix(flag.Arg(0), "-") {
38		log.Fatalf("Error: unknown flag: %s", flag.Arg(0))
39	}
40
41	i18n.Initialize()
42
43	if *flagInstall {
44		install(nil)
45	} else if *flagUninstall {
46		uninstall(nil)
47	} else {
48		_, window := guiInit()
49		if len(os.Args) > 1 {
50			go run(os.Args[1], window)
51		} else {
52			go guiInstaller(window)
53		}
54
55		// start the main loop
56		window.ShowAndRun()
57	}
58	log.Println("done")
59}
60
61func guiInit() (fyne.App, fyne.Window) {
62	application := app.New()
63	w := application.NewWindow(fmt.Sprintf("%s handler", setup.PROTOCOL))
64	w.Resize(fyne.NewSize(500, 200))
65	w.CenterOnScreen()
66	return application, w
67}
68
69func guiInstaller(window fyne.Window) {
70	lblIntro := widget.NewLabel(i18n.T("intro", nil))
71	//lblIntro.Wrapping = fyne.TextWrapWord // breaks window height, see fyne-io/fyne#4097
72	btnInstall := widget.NewButton(i18n.T("install", nil), func() { install(window) })
73	btnUninstall := widget.NewButton(i18n.T("uninstall", nil), func() { uninstall(window) })
74
75	window.SetContent(
76		container.New(
77			layout.NewVBoxLayout(),
78			lblIntro,
79			layout.NewSpacer(),
80			btnInstall,
81			btnUninstall,
82		),
83	)
84}
85
86func run(path string, window fyne.Window) {
87	// remove protocol and decode URL
88	log.Println("Input URL:", path)
89	r, _ := regexp.Compile("^.*?://")
90	path = r.ReplaceAllString(path, "")
91	path, _ = url.QueryUnescape(path)
92	log.Println("Extracted Path:", path)
93
94	// drive letter detection
95	isLetter, _ := regexp.MatchString("^/[C-Z]//", path)
96	if isLetter {
97		path = strings.Replace(path, "//", ":\\", 1)
98		path = path[1:]
99		log.Println("Drive letter path:", path)
100	}
101
102	// local path
103	path = setup.PreparePath(path, isLetter)
104	log.Println("Opening Path: ", path)
105	window.SetContent(widget.NewLabel(path))
106
107	err := setup.Run(path)
108	errHandler(err, "", window)
109	if err == nil {
110		window.Close()
111	}
112}
113
114func install(window fyne.Window) {
115	err := setup.Install()
116	errHandler(err, i18n.T("installed", nil), window)
117}
118
119func uninstall(window fyne.Window) {
120	err := setup.Uninstall()
121	errHandler(err, i18n.T("uninstalled", nil), window)
122}
123
124// Outputs either error or success message using the appropriate channel based on if
125// window is available or nil
126func errHandler(err error, success string, window fyne.Window) {
127	if err == nil {
128		if window == nil {
129			log.Println(success)
130		} else if success != "" {
131			dialog.ShowInformation(i18n.T("success", nil), success, window)
132		}
133	} else {
134		if window == nil {
135			log.Fatal(err)
136		} else {
137			dialog.ShowError(err, window)
138		}
139	}
140}
141
142func usage() {
143	fmt.Printf("Usage: %s %s://path \n", os.Args[0], setup.PROTOCOL)
144	fmt.Println("  Protocol handling. Will try to open the given path locally.")
145	fmt.Println()
146
147	fmt.Printf("Usage: %s [OPTION]\n", os.Args[0])
148	fmt.Println("  Install or uninstall the protocol handler")
149	flag.PrintDefaults()
150}
151