walkon 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/README.md +37 -0
- data/Rakefile +17 -0
- data/bin/walkon +11 -0
- data/lib/walkon.rb +18 -0
- data/lib/walkon/daemon.rb +46 -0
- data/lib/walkon/device.rb +18 -0
- data/lib/walkon/entrance_music.rb +34 -0
- data/lib/walkon/hci_tool.rb +31 -0
- data/lib/walkon/version.rb +3 -0
- data/spec/fixtures/music/00:A1:5D:AB:B2:E9.mp3 +0 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/walkon/daemon_spec.rb +27 -0
- data/spec/walkon/device_spec.rb +16 -0
- data/spec/walkon/entrance_music_spec.rb +26 -0
- data/spec/walkon/hci_tool_spec.rb +26 -0
- data/spec/walkon_spec.rb +7 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e98fa4a3f793072e126e54bb7885cc9ad4a11509
|
4
|
+
data.tar.gz: a613f716836c62e95d919db026bd3101395ffe62
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 94c888a21f894d3ec03066389834954bd53dc9da3bcff4b280e7d192b78a707a5a0066bbeb8d08adce83bd7305c4dfdb0b327c2a0c7fab3c121886767c1c00c5
|
7
|
+
data.tar.gz: 5b840b4c8e37048f83b8589ce8fc8d746737d182df1f05a6f866276bfba8a85dfdf446b8485359d35eece2b803eea504bda23009ad3ad4bd2e610ff76caa9bf5
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# Walkon
|
2
|
+
|
3
|
+
Walkon plays your entrance music. It's a daemon process that
|
4
|
+
periodically checks `hcitool scan` for new Bluetooth devices, then uses
|
5
|
+
their ESSIDs to find tracks to play as they leave or exit the network.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Walkon is best used on a **Raspberry Pi** with **Ubuntu**.
|
10
|
+
|
11
|
+
Install it yourself:
|
12
|
+
|
13
|
+
$ gem install walkon
|
14
|
+
|
15
|
+
Then, run:
|
16
|
+
|
17
|
+
$ walkon setup
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Place an MP3 in `/music` that corresponds with your device's ESSID.
|
22
|
+
So, if your device's name is "iPhone5", you would upload a track like
|
23
|
+
so:
|
24
|
+
|
25
|
+
$ scp your-track.mp3 walkon:/music/iPhone5.mp3
|
26
|
+
|
27
|
+
To find out more about how it works, read the [Documentation][docs].
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
1. Fork it
|
32
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
33
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
34
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
35
|
+
5. Create new Pull Request
|
36
|
+
|
37
|
+
[docs]: http://rdoc.info/github/tubbo/walkon
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new :test
|
6
|
+
|
7
|
+
desc "Provision a local development VM"
|
8
|
+
task :vm do
|
9
|
+
if `which vagrant` == ""
|
10
|
+
puts "Error: You must install Vagrant to use this feature."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
sh 'vagrant up'
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => %w(test build)
|
data/bin/walkon
ADDED
data/lib/walkon.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "walkon/version"
|
2
|
+
require "walkon/daemon"
|
3
|
+
|
4
|
+
module Walkon
|
5
|
+
def self.start
|
6
|
+
Walkon::Daemon.start
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.found_hcitool?
|
10
|
+
!!`hcitool -h`
|
11
|
+
rescue Errno::ENOENT
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.env
|
16
|
+
ENV['WALKON_ENV'] || 'development'
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'walkon/device'
|
2
|
+
require 'walkon/hci_tool'
|
3
|
+
|
4
|
+
# The process which listens for new Devices to come on the network, then
|
5
|
+
# immediately plays their entrance music and adds them to the collection
|
6
|
+
# so they won't be triggered again.
|
7
|
+
#
|
8
|
+
# A cron job restarts the daemon every night at 3:00am so the devices
|
9
|
+
# collection is reset and people are triggered again once they walk in
|
10
|
+
# the building.
|
11
|
+
|
12
|
+
module Walkon
|
13
|
+
class Daemon
|
14
|
+
attr_accessor :devices
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@devices = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.start
|
21
|
+
new.run
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
loop { check_for_devices }
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_for_devices
|
29
|
+
scanned_devices.each do |mac_address|
|
30
|
+
unless self.devices.include? mac_address
|
31
|
+
device = Device.new mac_address
|
32
|
+
play_entrance_music_for device
|
33
|
+
self.devices << Device.new(mac_address)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def scanned_devices
|
39
|
+
HciTool.scan
|
40
|
+
end
|
41
|
+
|
42
|
+
def play_entrance_music_for device
|
43
|
+
device.entrance_music.play if device.has_entrance_music?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'walkon/entrance_music'
|
2
|
+
|
3
|
+
# Represents a single Bluetooth device in the building.
|
4
|
+
|
5
|
+
module Walkon
|
6
|
+
class Device
|
7
|
+
attr_reader :mac_address, :entrance_music
|
8
|
+
|
9
|
+
def initialize with_mac_address
|
10
|
+
@mac_address = with_mac_address
|
11
|
+
@entrance_music = EntranceMusic.new self
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_entrance_music?
|
15
|
+
entrance_music.exists?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'walkon/device'
|
2
|
+
|
3
|
+
# Finds and plays the entrance music for a given device.
|
4
|
+
|
5
|
+
module Walkon
|
6
|
+
class EntranceMusic
|
7
|
+
attr_reader :device, :filename
|
8
|
+
|
9
|
+
def initialize from_device
|
10
|
+
@device = from_device
|
11
|
+
@filename = "#{prefix}/#{@device.mac_address}.mp3"
|
12
|
+
end
|
13
|
+
|
14
|
+
def exists?
|
15
|
+
File.exists? filename
|
16
|
+
end
|
17
|
+
|
18
|
+
alias present? exists?
|
19
|
+
|
20
|
+
def play
|
21
|
+
return false unless exists?
|
22
|
+
`xmms #{filename}`
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def prefix
|
27
|
+
if Walkon.env == 'test'
|
28
|
+
File.expand_path "../../../spec/fixtures/music", __FILE__
|
29
|
+
else
|
30
|
+
"/music"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# A collection of device names gathered from HciTool.
|
2
|
+
|
3
|
+
module Walkon
|
4
|
+
class HciTool
|
5
|
+
attr_accessor :results
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@results = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.scan
|
12
|
+
new.scan
|
13
|
+
end
|
14
|
+
|
15
|
+
def scan
|
16
|
+
@results = scan_results.reduce([]) do |collection, line|
|
17
|
+
line.scan FOR_MAC_ADDRESS do |mac_address|
|
18
|
+
collection << mac_address.first
|
19
|
+
end
|
20
|
+
|
21
|
+
collection
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
FOR_MAC_ADDRESS = /(..:..:..:..:..:..)/
|
27
|
+
def scan_results
|
28
|
+
`hcitool scan`.split "\n"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'walkon/daemon'
|
3
|
+
|
4
|
+
module Walkon
|
5
|
+
describe Daemon do
|
6
|
+
context "when a new device is detected" do
|
7
|
+
let(:mac_address) { "00:A1:5D:AB:B2:E9" }
|
8
|
+
|
9
|
+
before do
|
10
|
+
subject.stub(:scanned_devices) { [mac_address] }
|
11
|
+
subject.stub(:play_entrance_music_for) { |device| true }
|
12
|
+
subject.check_for_devices
|
13
|
+
end
|
14
|
+
|
15
|
+
it "adds the sample mac address to devices" do
|
16
|
+
expect(subject.devices.map(&:mac_address)).to include(mac_address)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "plays device's entrance music" do
|
20
|
+
expect(subject.devices).to_not be_empty
|
21
|
+
device = subject.devices.select { |dev| dev.mac_address == mac_address }.first
|
22
|
+
expect(device).to_not be_nil
|
23
|
+
expect(device).to have_entrance_music
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'walkon/device'
|
3
|
+
|
4
|
+
module Walkon
|
5
|
+
describe Device do
|
6
|
+
subject { Device.new '00:A1:5D:AB:B2:E9' }
|
7
|
+
|
8
|
+
it "requires a mac address for identification" do
|
9
|
+
expect(subject.mac_address).to_not be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "uses mac address to find entrance music in configured dir" do
|
13
|
+
expect(subject).to have_entrance_music
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'walkon/entrance_music'
|
3
|
+
|
4
|
+
module Walkon
|
5
|
+
describe EntranceMusic do
|
6
|
+
let(:mac_address) { "00:A1:5D:AB:B2:E9" }
|
7
|
+
let(:device) do
|
8
|
+
dev = double :device
|
9
|
+
dev.stub(:mac_address) { mac_address }
|
10
|
+
dev
|
11
|
+
end
|
12
|
+
subject { EntranceMusic.new device }
|
13
|
+
|
14
|
+
before do
|
15
|
+
subject.stub(:play) { "" }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "finds an mp3 file to play" do
|
19
|
+
expect(subject).to be_present
|
20
|
+
end
|
21
|
+
|
22
|
+
it "plays the mp3 file if found" do
|
23
|
+
expect(subject.play).to be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Walkon
|
4
|
+
describe HciTool do
|
5
|
+
let(:mac_address) { "00:A1:5D:AB:B2:E9" }
|
6
|
+
let(:sample_output) do
|
7
|
+
%(
|
8
|
+
Scanning....
|
9
|
+
#{mac_address} Nokia 6600
|
10
|
+
).split("\n")
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
subject.stub(:scan_results) { sample_output }
|
15
|
+
end
|
16
|
+
|
17
|
+
it "starts with no results" do
|
18
|
+
expect(subject.results).to be_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
it "finds mac addresses with a scan" do
|
22
|
+
expect(subject.scan).to_not be_empty
|
23
|
+
expect(subject.results.first).to eq(mac_address)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/walkon_spec.rb
ADDED
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: walkon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Scott
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Play your entrance music
|
70
|
+
email:
|
71
|
+
- tubbo@psychedeli.ca
|
72
|
+
executables:
|
73
|
+
- walkon
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- bin/walkon
|
78
|
+
- lib/walkon/daemon.rb
|
79
|
+
- lib/walkon/device.rb
|
80
|
+
- lib/walkon/entrance_music.rb
|
81
|
+
- lib/walkon/hci_tool.rb
|
82
|
+
- lib/walkon/version.rb
|
83
|
+
- lib/walkon.rb
|
84
|
+
- spec/fixtures/music/00:A1:5D:AB:B2:E9.mp3
|
85
|
+
- spec/spec_helper.rb
|
86
|
+
- spec/walkon/daemon_spec.rb
|
87
|
+
- spec/walkon/device_spec.rb
|
88
|
+
- spec/walkon/entrance_music_spec.rb
|
89
|
+
- spec/walkon/hci_tool_spec.rb
|
90
|
+
- spec/walkon_spec.rb
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
homepage: http://github.com/tubbo/walkon
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.0.3
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Play your entrance music
|
117
|
+
test_files:
|
118
|
+
- spec/fixtures/music/00:A1:5D:AB:B2:E9.mp3
|
119
|
+
- spec/spec_helper.rb
|
120
|
+
- spec/walkon/daemon_spec.rb
|
121
|
+
- spec/walkon/device_spec.rb
|
122
|
+
- spec/walkon/entrance_music_spec.rb
|
123
|
+
- spec/walkon/hci_tool_spec.rb
|
124
|
+
- spec/walkon_spec.rb
|