walkon 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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)
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'walkon'
5
+
6
+ unless Walkon.found_hcitool?
7
+ puts "Error: You need BlueZ to use this software. Exiting.."
8
+ exit 1
9
+ end
10
+
11
+ Walkon.start
@@ -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
@@ -0,0 +1,3 @@
1
+ module Walkon
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'bundler/setup'
2
+ require 'rspec'
3
+ require 'pry'
4
+
5
+ ENV['WALKON_ENV'] ||= "test"
6
+
7
+ require 'walkon'
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Walkon do
4
+ it "runs a daemon for playing entrance music" do
5
+ expect(Walkon).to respond_to :start
6
+ end
7
+ end
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