bluemoon 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +56 -0
- data/bin/bluemoon +20 -0
- data/bin/get-location +0 -0
- data/lib/bluemoon.rb +28 -0
- data/lib/bluemoon/area.rb +50 -0
- data/lib/bluemoon/bluetooth.rb +19 -0
- data/lib/bluemoon/help.rb +23 -0
- data/lib/bluemoon/location.rb +72 -0
- data/lib/bluemoon/notify.rb +39 -0
- data/lib/bluemoon/version.rb +3 -0
- metadata +99 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 37873ef2b28838b815a4cd521069a296aa75d663
|
|
4
|
+
data.tar.gz: ccd63c187ed61d588f6440271c45f0174911073d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: cb8c7781c38fd2a7317c5a32cea48d1f72dd8198796743a4fc3401a35cd5a62143eb00f8bf5d9dd204e19ead0f006591df8a8590a51ac31a84ee1aec542135b5
|
|
7
|
+
data.tar.gz: c0a3bcdfc95bce2e2152166ba81447ac8dfde0c3dd9e9c81290b8f87143d5c869306e30a05f036392570f7696ba3c6035bd2dd837c7f7ce2d4b1ab2886abe21f
|
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# bluemoon
|
|
2
|
+
|
|
3
|
+
Enable or disable bluetooth on OS X based on your current location
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Why?
|
|
7
|
+
|
|
8
|
+
I use bluetooth on my Mac at the office for my wireless keyboard and mouse. At home or at the coffee shop, however, I don't use bluetooth at all. So bluetooth is generally running, and:
|
|
9
|
+
|
|
10
|
+
* draining my battery
|
|
11
|
+
* interfering with my wireless connection
|
|
12
|
+
|
|
13
|
+
until I remember to turn it off. And then, of course, I have to turn it back on at the office.
|
|
14
|
+
|
|
15
|
+
Bluemoon will handle powering your MacBook's bluetooth connection based on your location.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
I'm currently working on a homebrew recipe. Until then:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
brew install blueutil
|
|
23
|
+
brew install sleepwatcher
|
|
24
|
+
brew install terminal-notifier
|
|
25
|
+
gem install bluemoon --no-wrappers
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Configuration
|
|
29
|
+
|
|
30
|
+
You'll probably want `bluemoon bootup` to run everytime you reboot:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
crontab -e
|
|
34
|
+
@reboot bluemoon bootup
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To be useful, you'll need to add at least one location you want Bluetooth enabled.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
bluemoon add # current location
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## TODO
|
|
45
|
+
|
|
46
|
+
* Add IP address or router Mac address support
|
|
47
|
+
* Create a homebrew recipe
|
|
48
|
+
* Vendor `get-location` properly so it installs without the `--no-wrappers` flag
|
|
49
|
+
* Create a homebrew recipe so `brew install bluemoon` works
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Acknowledgements
|
|
53
|
+
|
|
54
|
+
The [get-location helper](https://github.com/lindes/get-location) was created by @lindes. Thank you.
|
|
55
|
+
|
|
56
|
+
@jonahaaron proposed IP-address support.
|
data/bin/bluemoon
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
%w[bluemoon json plist].each do |dependency|
|
|
4
|
+
begin
|
|
5
|
+
require dependency
|
|
6
|
+
rescue LoadError => e
|
|
7
|
+
abort "Unabled to find gem '#{dependency}'. Please run `gem install #{dependency}` to continue."
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
case ARGV.shift
|
|
12
|
+
when 'add' then Bluemoon::Area.add
|
|
13
|
+
when 'bootup' then Bluemoon.bootup
|
|
14
|
+
when 'debug' then Bluemoon::Location.debug
|
|
15
|
+
when 'list' then Bluemoon::Area.list
|
|
16
|
+
when 'open' then Bluemoon::Location.current.open
|
|
17
|
+
when 'remove' then Bluemoon::Area.remove(ARGV.shift)
|
|
18
|
+
when 'run' then Bluemoon.run
|
|
19
|
+
else Bluemoon::Help.show
|
|
20
|
+
end
|
data/bin/get-location
ADDED
|
Binary file
|
data/lib/bluemoon.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Bluemoon
|
|
2
|
+
autoload :Area, 'bluemoon/area'
|
|
3
|
+
autoload :Bluetooth, 'bluemoon/bluetooth'
|
|
4
|
+
autoload :Help, 'bluemoon/help'
|
|
5
|
+
autoload :Location, 'bluemoon/location'
|
|
6
|
+
autoload :Notify, 'bluemoon/notify'
|
|
7
|
+
|
|
8
|
+
def self.bootup
|
|
9
|
+
system "sleepwatcher --displaywakeup 'bluemoon run'"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.run
|
|
13
|
+
# We disable Bluetooth up here,
|
|
14
|
+
# because disabling it helps us connect to wifi faster
|
|
15
|
+
just_disabled = Bluetooth.off
|
|
16
|
+
|
|
17
|
+
if Area.all.any? { |area| area.contains?(Location.current) }
|
|
18
|
+
Bluetooth.on
|
|
19
|
+
|
|
20
|
+
just_disabled or Notify.success('Enabling Bluetooth')
|
|
21
|
+
else
|
|
22
|
+
just_disabled and Notify.success('Disabling Bluetooth')
|
|
23
|
+
end
|
|
24
|
+
rescue
|
|
25
|
+
Bluetooth.on
|
|
26
|
+
Notify.handle($!)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Bluemoon
|
|
2
|
+
class Area < Struct.new(:coordinates)
|
|
3
|
+
PROXIMITY = 400
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
def add
|
|
7
|
+
puts "Querying location. This may take a few moments..."
|
|
8
|
+
|
|
9
|
+
File.open(plist_filename, 'w+') do |file|
|
|
10
|
+
file.write [*all, Location.current].map(&:coordinates).uniq.to_plist
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
puts "Added #{Location.current} to list of places to enable bluetooth at."
|
|
14
|
+
puts Location.current.url
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def all
|
|
18
|
+
Array(Plist::parse_xml(plist_filename)).map do |area|
|
|
19
|
+
self.new(area)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def list
|
|
24
|
+
all.each_with_index do |location, i|
|
|
25
|
+
puts "#{(i + 1).to_s.ljust(all.count.to_s.length)}. #{location}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def plist_filename
|
|
30
|
+
"#{ENV['HOME']}/Library/Preferences/com.bluemoon.locations"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def remove(i)
|
|
34
|
+
File.open(plist_filename, 'w+') do |file|
|
|
35
|
+
file.write all.tap { |a| a.delete(i.to_i - 1) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
list
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def contains?(location)
|
|
43
|
+
location.distance(coordinates) < PROXIMITY
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_s
|
|
47
|
+
coordinates.join(', ')
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Bluemoon
|
|
2
|
+
class Help
|
|
3
|
+
def self.show
|
|
4
|
+
puts <<-HELP
|
|
5
|
+
|
|
6
|
+
bluemoon
|
|
7
|
+
Enable or disable bluetooth on OS X based on your current location
|
|
8
|
+
|
|
9
|
+
bootup :: Runs `bluemoon run` whenever your display wakes up.
|
|
10
|
+
add :: Enable bluetooth at your current location
|
|
11
|
+
list :: List all locations where bluetooth is enabled
|
|
12
|
+
remove # :: Remove the numbered location (e.g. `bluemoon remove 3`)
|
|
13
|
+
run :: Enable or disable bluetooth based on your proxmity to the location
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
debug :: Show current location and meters from office.
|
|
17
|
+
help :: Displays this help message.
|
|
18
|
+
open :: Open your current location in Google Maps
|
|
19
|
+
|
|
20
|
+
HELP
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Bluemoon
|
|
2
|
+
class Location < Struct.new(:coordinates)
|
|
3
|
+
class << self
|
|
4
|
+
def current
|
|
5
|
+
@@current ||= self.new(JSON.parse(`get-location -f json`)['coordinates'])
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def debug
|
|
9
|
+
puts "Querying location. This generally takes 10-20 seconds. Press any key to skip."
|
|
10
|
+
|
|
11
|
+
Thread.new do
|
|
12
|
+
display_debug_message(
|
|
13
|
+
Area.all.join(', '),
|
|
14
|
+
Area::PROXIMITY,
|
|
15
|
+
current.to_s,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
Kernel.exit
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if $stdin.gets.length > 0
|
|
22
|
+
display_debug_message(OFFICE.join(', '), PROXIMITY)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def display_debug_message(office, proximity, location = 'Skipped', distance = '?', in_range = 'Maybe')
|
|
27
|
+
puts <<-DEBUG
|
|
28
|
+
|
|
29
|
+
Office: #{office}
|
|
30
|
+
Proximity: You must be #{proximity} meters from the office to enable bluetooth.
|
|
31
|
+
Location: #{location}
|
|
32
|
+
Distance: #{distance} meters
|
|
33
|
+
In range: #{in_range}
|
|
34
|
+
|
|
35
|
+
DEBUG
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Kindly stolen wholesale from
|
|
40
|
+
# http://stackoverflow.com/a/12969617/615412
|
|
41
|
+
def distance(from)
|
|
42
|
+
a, b = coordinates.dup, from
|
|
43
|
+
|
|
44
|
+
rad_per_deg = Math::PI/180 # PI / 180
|
|
45
|
+
rkm = 6371 # Earth radius in kilometers
|
|
46
|
+
rm = rkm * 1000 # Radius in meters
|
|
47
|
+
|
|
48
|
+
dlon_rad = (b[1]-a[1]) * rad_per_deg # Delta, converted to rad
|
|
49
|
+
dlat_rad = (b[0]-a[0]) * rad_per_deg
|
|
50
|
+
|
|
51
|
+
lat1_rad, lon1_rad = a.map! {|i| i * rad_per_deg }
|
|
52
|
+
lat2_rad, lon2_rad = b.map! {|i| i * rad_per_deg }
|
|
53
|
+
|
|
54
|
+
a = Math.sin(dlat_rad/2)**2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad/2)**2
|
|
55
|
+
c = 2 * Math.asin(Math.sqrt(a))
|
|
56
|
+
|
|
57
|
+
rm * c # Delta in meters
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def open
|
|
61
|
+
`open #{url}`
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_s
|
|
65
|
+
"#{coordinates.join(', ')}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def url
|
|
69
|
+
"https://www.google.com/maps/@#{coordinates.join(',')},15z"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Bluemoon
|
|
2
|
+
class Notify
|
|
3
|
+
def self.handle(exception)
|
|
4
|
+
"#{ENV['HOME']}/bluemoon-error-logs.txt".tap do |error_log|
|
|
5
|
+
File.open(error_log, 'a') do |file|
|
|
6
|
+
file.write exception.message
|
|
7
|
+
file.write exception.backtrace.join("\n")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Notify.failure(
|
|
11
|
+
"Failed to gather location, enabled bluetooth",
|
|
12
|
+
"-execute 'open #{error_log}'"
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
puts exception.message
|
|
17
|
+
puts *exception.backtrace
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.success(message)
|
|
21
|
+
puts message
|
|
22
|
+
|
|
23
|
+
`terminal-notifier-success \
|
|
24
|
+
-message "#{message}" \
|
|
25
|
+
-title "Bluemoon" \
|
|
26
|
+
-group bluemoon &>/dev/null`
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.failure(message, flags = '')
|
|
30
|
+
puts message
|
|
31
|
+
|
|
32
|
+
`terminal-notifier-failed \
|
|
33
|
+
-message "#{message}" \
|
|
34
|
+
#{flags} \
|
|
35
|
+
-title "Bluemoon" \
|
|
36
|
+
-group bluemoon &>/dev/null`
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bluemoon
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nathaniel Jones
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-05-26 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '>='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - '>='
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: json
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: plist
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: Enable or disable bluetooth on OS X based on your current location
|
|
56
|
+
email: nj@third.io
|
|
57
|
+
executables:
|
|
58
|
+
- bluemoon
|
|
59
|
+
- get-location
|
|
60
|
+
extensions: []
|
|
61
|
+
extra_rdoc_files: []
|
|
62
|
+
files:
|
|
63
|
+
- lib/bluemoon/area.rb
|
|
64
|
+
- lib/bluemoon/bluetooth.rb
|
|
65
|
+
- lib/bluemoon/help.rb
|
|
66
|
+
- lib/bluemoon/location.rb
|
|
67
|
+
- lib/bluemoon/notify.rb
|
|
68
|
+
- lib/bluemoon/version.rb
|
|
69
|
+
- lib/bluemoon.rb
|
|
70
|
+
- README.md
|
|
71
|
+
- LICENSE
|
|
72
|
+
- bin/bluemoon
|
|
73
|
+
- bin/get-location
|
|
74
|
+
homepage: http://github.com/nthj/bluemoon
|
|
75
|
+
licenses:
|
|
76
|
+
- MIT
|
|
77
|
+
metadata: {}
|
|
78
|
+
post_install_message:
|
|
79
|
+
rdoc_options: []
|
|
80
|
+
require_paths:
|
|
81
|
+
- lib
|
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - '>='
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '0'
|
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - '>='
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '0'
|
|
92
|
+
requirements:
|
|
93
|
+
- blueutil, sleepwatcher, get-location, terminal-notifier
|
|
94
|
+
rubyforge_project:
|
|
95
|
+
rubygems_version: 2.1.11
|
|
96
|
+
signing_key:
|
|
97
|
+
specification_version: 4
|
|
98
|
+
summary: bluemoon
|
|
99
|
+
test_files: []
|