-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Jérôme Schneider
committed
Oct 2, 2018
0 parents
commit 73ece87
Showing
16 changed files
with
369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dist | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Bowser.app: clean Makefile src/*.go src/*.h src/*.m src/*.plist assets/*.icns assets/*.png | ||
mkdir -p dist/Bowser.app/Contents/MacOS dist/Bowser.app/Contents/Resources | ||
cd src && go build -i -o ../dist/Bowser.app/Contents/MacOS/bowser | ||
cp assets/bowser.png dist/Bowser.app/Contents/MacOS | ||
cp src/Info.plist dist/Bowser.app/Contents | ||
cp assets/icon.icns dist/Bowser.app/Contents/Resources | ||
|
||
.PHONY: install | ||
install: Bowser.app | ||
cp -Rf dist/Bowser.app /Applications | ||
|
||
.PHONY: clean | ||
clean: | ||
-rm -Rf dist/Bowser.app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# bowser - Browser switch | ||
|
||
Bowser is a MacOS application that selects the browser to open for a URL based on rules you define. | ||
|
||
My use case is to have 2 default browsers : one for development (Chrome), and one for surf (Safari). | ||
|
||
## Install from binary releases | ||
|
||
TODO | ||
|
||
## Install from source | ||
|
||
The installation from source requires the Apple clang environment (XCode) and Go 1.8+ | ||
|
||
```sh | ||
$ git clone https://github.com/netgusto/bowser | ||
$ cd bowser | ||
$ make install | ||
``` | ||
|
||
## Setup as default browser |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>app</key> | ||
<string>com.bohemiancoding.sketch</string> | ||
<key>build</key> | ||
<integer>5370</integer> | ||
<key>commit</key> | ||
<string>38aeabf36c76d40a8ed2d256f8f3b9492c3dac07</string> | ||
<key>fonts</key> | ||
<array/> | ||
<key>length</key> | ||
<integer>21163</integer> | ||
<key>version</key> | ||
<integer>18</integer> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
18 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>CFBundleExecutable</key> | ||
<string>bowser</string> | ||
<key>CFBundleIconFile</key> | ||
<string>icon.icns</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>com.netgusto.bowser</string> | ||
<key>NSHighResolutionCapable</key> | ||
<true/> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>Bowser</string> | ||
<key>CFBundlePackageType</key> | ||
<string>APPL</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0.0</string> | ||
<key>CFBundleVersion</key> | ||
<string>20</string> | ||
<key>LSUIElement</key> | ||
<true/> | ||
<key>LSBackgroundOnly</key> | ||
<true/> | ||
<key>CFBundleURLTypes</key> | ||
<array> | ||
<dict> | ||
<key>CFBundleURLName</key> | ||
<string>http URL</string> | ||
<key>CFBundleURLSchemes</key> | ||
<array> | ||
<string>http</string> | ||
</array> | ||
</dict> | ||
<dict> | ||
<key>CFBundleURLName</key> | ||
<string>Secure http URL</string> | ||
<key>CFBundleURLSchemes</key> | ||
<array> | ||
<string>https</string> | ||
</array> | ||
</dict> | ||
<dict> | ||
<key>CFBundleURLName</key> | ||
<string>Local file URL</string> | ||
<key>CFBundleURLSchemes</key> | ||
<array> | ||
<string>file</string> | ||
</array> | ||
</dict> | ||
</array> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#import <Foundation/Foundation.h> | ||
|
||
extern void ReceiveURL(char*); | ||
|
||
@interface GoPasser : NSObject | ||
+ (void)handleGetURLEvent:(NSAppleEventDescriptor *)event; | ||
@end | ||
|
||
void StartURLHandler(void); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include "handler.h" | ||
|
||
@implementation GoPasser | ||
+ (void)handleGetURLEvent:(NSAppleEventDescriptor *)event | ||
{ | ||
ReceiveURL([[[event paramDescriptorForKeyword:keyDirectObject] stringValue] UTF8String]); | ||
} | ||
@end | ||
|
||
void StartURLHandler(void) { | ||
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; | ||
[appleEventManager setEventHandler:[GoPasser class] | ||
andSelector:@selector(handleGetURLEvent:) | ||
forEventClass:kInternetEventClass andEventID:kAEGetURL]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"regexp" | ||
|
||
gosxnotifier "github.com/deckarep/gosx-notifier" | ||
"github.com/skratchdot/open-golang/open" | ||
) | ||
|
||
var devBrowser = "Google Chrome" | ||
var surfBrowser = "Safari" | ||
|
||
func handleURL(config Config, url string) chan interface{} { | ||
wait := make(chan interface{}) | ||
|
||
go func() { | ||
log.Println("Received URL") | ||
|
||
var matchedBrowser *Browser | ||
|
||
for _, browser := range config.Browsers { | ||
for _, rgx := range browser.Match { | ||
success, _ := regexp.MatchString(rgx, url) | ||
if success { | ||
matchedBrowser = &browser | ||
break | ||
} | ||
} | ||
|
||
if matchedBrowser != nil { | ||
break | ||
} | ||
} | ||
|
||
if matchedBrowser == nil { | ||
// Looking for defautl browser | ||
for _, browser := range config.Browsers { | ||
if browser.Alias == "Default" { | ||
matchedBrowser = &browser | ||
break | ||
} | ||
} | ||
} | ||
|
||
if matchedBrowser == nil { | ||
// Cannot find default browser; fall back to Safari | ||
open.RunWith(url, "Safari") | ||
// open.RunWith("https://github.com/netgusto/bowser", "Safari") | ||
// open.RunWith("/tmp/hello.txt", "TextEdit") | ||
|
||
notifyProblem( | ||
"Cannot find a default browser - falling back to Safari\nSee https://github.com/netgusto/bowser", | ||
"Bowser - No default browser", | ||
) | ||
|
||
} else { | ||
err := open.RunWith(url, matchedBrowser.App) | ||
if err != nil { | ||
log.Println(err) | ||
|
||
if err2 := open.RunWith(url, "Safari"); err2 == nil { | ||
notifyProblem( | ||
"URL Matched \""+matchedBrowser.Alias+"\" but failed to open \""+matchedBrowser.App+"\" - Falling back to Safari", | ||
"Bowser - Problem with browser "+matchedBrowser.Alias, | ||
) | ||
} else { | ||
notifyProblem( | ||
"URL Matched \""+matchedBrowser.Alias+"\" but failed to open \""+matchedBrowser.App+"\" - Could not fall back to Safari", | ||
"Bowser - Problem with browser "+matchedBrowser.Alias, | ||
) | ||
} | ||
} | ||
} | ||
|
||
wait <- nil | ||
}() | ||
|
||
return wait | ||
} | ||
|
||
func notifyProblem(msg string, title string) { | ||
note := gosxnotifier.NewNotification(msg) | ||
note.Title = title | ||
note.AppIcon = getNotificationIconPath() | ||
note.Link = "https://github.com/netgusto/bowser#setup-default-browser" | ||
note.Push() | ||
} | ||
|
||
func getNotificationIconPath() string { | ||
dir, err := filepath.Abs(filepath.Dir(os.Args[0])) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
return dir + "/" + "bowser.png" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package main | ||
|
||
// From https://gist.github.com/nathankerr/38d8b0d45590741b57f5f79be336f07c | ||
|
||
/* | ||
#cgo CFLAGS: -x objective-c -Wno-incompatible-pointer-types-discards-qualifiers | ||
#cgo LDFLAGS: -framework Foundation | ||
#include "handler.h" | ||
*/ | ||
import "C" | ||
|
||
import ( | ||
"github.com/andlabs/ui" | ||
) | ||
|
||
//export ReceiveURL | ||
func ReceiveURL(u *C.char) { | ||
urlStream <- C.GoString(u) | ||
} | ||
|
||
func listen(config Config) chan bool { | ||
|
||
urlStream = make(chan string, 1) // the event handler blocks!, so buffer the channel at least once to get the first message | ||
C.StartURLHandler() | ||
|
||
done := make(chan bool) | ||
|
||
ui.Main(func() { | ||
ui.QueueMain(func() { ui.Quit() }) | ||
|
||
go func() { | ||
for url := range urlStream { | ||
<-handleURL(config, url) | ||
done <- true | ||
} | ||
}() | ||
}) | ||
|
||
return done | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"log/syslog" | ||
"time" | ||
|
||
"github.com/arkan/dotconfig" | ||
gosxnotifier "github.com/deckarep/gosx-notifier" | ||
"github.com/skratchdot/open-golang/open" | ||
) | ||
|
||
var urlStream chan string | ||
var appname = "bowser" | ||
|
||
func main() { | ||
|
||
config, err := getConfig() | ||
if err != nil { | ||
log.Panicln(err) | ||
} | ||
|
||
if config.Debug { | ||
// Configure logger to write to the syslog | ||
logwriter, err := syslog.New(syslog.LOG_NOTICE, appname) | ||
if err == nil { | ||
log.SetOutput(logwriter) | ||
} | ||
} | ||
|
||
select { | ||
case <-listen(config): | ||
if config.IsDefault { | ||
note := gosxnotifier.NewNotification("A default configuration has been set for Bowser in ~/.config/bowser/config.yml") | ||
note.Title = "Bowser - Please configure" | ||
note.AppIcon = getNotificationIconPath() | ||
note.Link = "https://github.com/netgusto/bowser#setup" | ||
note.Push() | ||
} | ||
log.Println("Done") | ||
case <-time.After(300 * time.Millisecond): | ||
open.RunWith("https://github.com/netgusto/bowser", "Safari") | ||
log.Println("Not received any URL after .1s; exiting") | ||
} | ||
} | ||
|
||
// Config ... | ||
type Config struct { | ||
Debug bool `yaml:"debug"` | ||
Browsers []Browser `yaml:"browsers,omitempty"` | ||
IsDefault bool `yaml:"-"` | ||
} | ||
|
||
// Browser ... | ||
type Browser struct { | ||
Alias string `yaml:"alias"` | ||
App string `yaml:"app,omitempty"` | ||
Match []string `yaml:"match,omitempty"` | ||
} | ||
|
||
func getConfig() (Config, error) { | ||
config := Config{} | ||
|
||
if err := dotconfig.Load(appname, &config); err != nil { | ||
if err == dotconfig.ErrConfigNotFound { | ||
initDefaultConfig(&config) | ||
if err := dotconfig.Save(appname, config); err != nil { | ||
return config, err | ||
} | ||
} | ||
} else if err != nil { | ||
return config, err | ||
} | ||
|
||
return config, nil | ||
} | ||
|
||
func initDefaultConfig(config *Config) { | ||
config.IsDefault = true | ||
config.Debug = false | ||
config.Browsers = []Browser{ | ||
Browser{ | ||
Alias: "Default", | ||
App: "Safari", | ||
}, | ||
// Browser{ | ||
// Alias: "Dev", | ||
// App: "Google Chrome", | ||
// Match: []string{ | ||
// "^https?://127.0.0.1", | ||
// "^https?://localhost", | ||
// }, | ||
// }, | ||
} | ||
} |