altum 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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/README +18 -0
- data/Rakefile +12 -0
- data/altum.gemspec +23 -0
- data/altum.js +28 -0
- data/lib/altum/version.rb +3 -0
- data/lib/altum.rb +101 -0
- data/spec/altum_spec.rb +92 -0
- metadata +106 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
_ _ _ _ _ _
|
3
|
+
/ /\ _\ \ /\ \ /\_\ /\_\/\_\ _
|
4
|
+
/ / \ /\__ \ \_\ \ / / / _ / / / / //\_\
|
5
|
+
/ / /\ \ / /_ \_\ /\__ \\ \ \__ /\_\ /\ \/ \ \/ / /
|
6
|
+
/ / /\ \ \ / / /\/_/ / /_ \ \\ \___\ / / // \____\__/ /
|
7
|
+
/ / / \ \ \ / / / / / /\ \ \\__ / / / // /\/________/
|
8
|
+
/ / /___/ /\ \ / / / / / / \/_// / / / / // / /\/_// / /
|
9
|
+
/ / /_____/ /\ \ / / / ____ / / / / / / / / // / / / / /
|
10
|
+
/ /_________/\ \ \ / /_/_/ ___/\ / / / / / /___/ / // / / / / /
|
11
|
+
/ / /_ __\ \_\/_______/\__\//_/ / / / /____\/ / \/_/ / / /
|
12
|
+
\_\___\ /____/_/\_______\/ \_\/ \/_________/ \/_/
|
13
|
+
|
14
|
+
|
15
|
+
Altum uses the magic of Pusher and websockets to drive a ShowOff
|
16
|
+
presentation remotely. See the Rocco geneerated docs for more information:
|
17
|
+
|
18
|
+
<http://lmarburger.github.com/altum/>
|
data/Rakefile
ADDED
data/altum.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/altum/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Larry Marburger"]
|
6
|
+
gem.email = ["larry@marburger.cc"]
|
7
|
+
gem.description = %q{Present remotely}
|
8
|
+
gem.summary = %q{Altum uses the magic of Pusher and websockets to drive a ShowOff presentation remotely. The simplest tool when you need to walk through a deck on a conference call.}
|
9
|
+
gem.homepage = "http://lmarburger.github.com/altum/"
|
10
|
+
|
11
|
+
gem.add_dependency 'pusher'
|
12
|
+
gem.add_dependency 'rack'
|
13
|
+
|
14
|
+
gem.add_development_dependency 'webmock'
|
15
|
+
gem.add_development_dependency 'wrong'
|
16
|
+
|
17
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
gem.files = `git ls-files`.split("\n")
|
19
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
gem.name = "altum"
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
gem.version = Altum::VERSION
|
23
|
+
end
|
data/altum.js
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
/******************************************************
|
2
|
+
** Copy the latest pusher.min.js and paste it here. **
|
3
|
+
** http://js.pusherapp.com/1.9/pusher.min.js **
|
4
|
+
******************************************************/
|
5
|
+
|
6
|
+
var presenter = /presenter=(.*)/.exec(window.location.search),
|
7
|
+
sekret = presenter && presenter[1];
|
8
|
+
|
9
|
+
if (sekret) {
|
10
|
+
$(function() {
|
11
|
+
$('body').bind('showoff:show', function() {
|
12
|
+
$.post('/slide', { key: sekret, number: slidenum });
|
13
|
+
});
|
14
|
+
});
|
15
|
+
|
16
|
+
} else {
|
17
|
+
|
18
|
+
// Enable pusher logging - don't include this in production
|
19
|
+
Pusher.log = function(message) {
|
20
|
+
if (window.console && window.console.log) window.console.log(message);
|
21
|
+
};
|
22
|
+
|
23
|
+
new Pusher('06d2e0409a41c6e5a7d4')
|
24
|
+
.subscribe('presenter')
|
25
|
+
.bind('slide_change', function(data) {
|
26
|
+
gotoSlide(data.slide);
|
27
|
+
});
|
28
|
+
}
|
data/lib/altum.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# **Altum** uses the magic of Pusher and websockets to drive a [ShowOff][]
|
2
|
+
# presentation remotely.
|
3
|
+
#
|
4
|
+
# Altum consists of a piece of Rack middleware and some JavaScript that keeps
|
5
|
+
# viewers in sync with the presenter. Getting started is easy.
|
6
|
+
#
|
7
|
+
# Install Altum with Rubygems:
|
8
|
+
#
|
9
|
+
# gem install altum
|
10
|
+
#
|
11
|
+
# ShowOff will create a `config.ru` file when using the command `showoff heroku`
|
12
|
+
# or simply create one yourself. Add Altum as you would any other Rack
|
13
|
+
# middleware supplying it with your Pusher connection URL and a key used to
|
14
|
+
# identify the presenter.
|
15
|
+
#
|
16
|
+
# require 'showoff'
|
17
|
+
# require 'altum'
|
18
|
+
#
|
19
|
+
# use Altum, :pusher_url => ENV['PUSHER_URL'], :key => 'sekret'
|
20
|
+
# run ShowOff.new
|
21
|
+
#
|
22
|
+
# Next, download [altum.js][] into your presentation directory. Copy the code
|
23
|
+
# from the latest [pusher.min.js][] and paste it at the top of `altum.js`.
|
24
|
+
#
|
25
|
+
# Start the presentation locally with `rackup` or deploy it to heroku using
|
26
|
+
# `showoff heroku`. You're ready to present! Open the presentation as the
|
27
|
+
# presenter by visiting
|
28
|
+
# [http://_your-app-name_.heroku.com?presenter=sekret][presenter] and ask those
|
29
|
+
# observing to follow along with you at
|
30
|
+
# [http://_your-app-name_.heroku.com][observer]. Your observer's browsers will
|
31
|
+
# follow along with you as you move through your deck; forward, backward, and
|
32
|
+
# jumping to a specific slide.
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# [showoff]: https://github.com/schacon/showoff
|
36
|
+
# [altum.js]: https://github.com/lmarburger/altum/blob/master/altum.js
|
37
|
+
# [pusher.min.js]: http://js.pusherapp.com/1.9/pusher.min.js
|
38
|
+
# [presenter]: http://your-app-name.heroku.com?presenter=sekret
|
39
|
+
# [observer]: http://your-app-name.heroku.com
|
40
|
+
|
41
|
+
require 'altum/version'
|
42
|
+
require 'pusher'
|
43
|
+
|
44
|
+
# `Altum.new` takes the downstream `app` and an `options` hash. The `options`
|
45
|
+
# hash respects two members:
|
46
|
+
#
|
47
|
+
# * `:pusher_url`: the Pusher connection URL passed to `Pusher.url=`. If you're
|
48
|
+
# using Pusher as a Heroku add-on, it will be in the environment variable
|
49
|
+
# `PUSHER_URL`.
|
50
|
+
#
|
51
|
+
# * `:key`: an optional secret key to identify the presenter pass as a query
|
52
|
+
# string parameter. If `:key` is nil or doesn't exist, the default "sekret" is
|
53
|
+
# used. Append `?presenter=sekret` to the ShowOff URL to drive the
|
54
|
+
# presentation.
|
55
|
+
class Altum
|
56
|
+
|
57
|
+
def initialize(app, options)
|
58
|
+
@app = app
|
59
|
+
@key = options[:key] || 'sekret'
|
60
|
+
|
61
|
+
Pusher.url = options[:pusher_url]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Listen for slide change commands from the presenter and send the current
|
65
|
+
# slide out to all those watching. Silently ignore requests from a presenter
|
66
|
+
# using an incorrect key.
|
67
|
+
def call(env)
|
68
|
+
request = Rack::Request.new env
|
69
|
+
|
70
|
+
if slide_path? request
|
71
|
+
change_slide request if presenter?(request)
|
72
|
+
|
73
|
+
[ 204, {}, [] ]
|
74
|
+
else
|
75
|
+
@app.call env
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
# Respond only to requests for `/slide`.
|
82
|
+
def slide_path?(request)
|
83
|
+
request.path == '/slide'
|
84
|
+
end
|
85
|
+
|
86
|
+
# Match the key supplied in the request with the key used when the middlware
|
87
|
+
# was configured.
|
88
|
+
def presenter?(request)
|
89
|
+
request.params['key'] == @key
|
90
|
+
end
|
91
|
+
|
92
|
+
# Grab the current slide number from the `number` parameter of the request.
|
93
|
+
# Pass it to those observing by triggering the `presenter` channel's
|
94
|
+
# `slide_change` event.
|
95
|
+
def change_slide(request)
|
96
|
+
Pusher['presenter'].trigger('slide_change', {
|
97
|
+
'slide' => request.params['number']
|
98
|
+
})
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
data/spec/altum_spec.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'webmock/minitest'
|
4
|
+
require 'wrong/adapters/minitest'
|
5
|
+
|
6
|
+
require 'altum'
|
7
|
+
require 'rack/mock'
|
8
|
+
|
9
|
+
class DummyApp
|
10
|
+
def call(env)
|
11
|
+
[ 200, {}, ["Hello World"] ]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Altum do
|
16
|
+
|
17
|
+
def pusher_url
|
18
|
+
'http://1234:4321@api.pusherapp.com/apps/1324'
|
19
|
+
end
|
20
|
+
|
21
|
+
def request(options = {})
|
22
|
+
options = options.merge :pusher_url => pusher_url
|
23
|
+
|
24
|
+
Rack::MockRequest.new Altum.new(DummyApp.new, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def stub_push
|
28
|
+
stub_request(:post, %r{\Ahttp://api\.pusherapp\.com/apps/1324/channels/presenter/events\?auth_key=1234&.*&name=slide_change\Z}).
|
29
|
+
to_return(:status => 202)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'sets up Pusher' do
|
33
|
+
Altum.new(DummyApp.new, :pusher_url => pusher_url)
|
34
|
+
|
35
|
+
assert { Pusher.host == 'api.pusherapp.com' }
|
36
|
+
assert { Pusher.port == 80 }
|
37
|
+
assert { Pusher.key == '1234' }
|
38
|
+
assert { Pusher.secret == '4321' }
|
39
|
+
assert { Pusher.app_id == '1324' }
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'passes along irrlevant requests' do
|
43
|
+
res = request.get '/'
|
44
|
+
|
45
|
+
assert { res.ok? }
|
46
|
+
assert { res.body == 'Hello World' }
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'responds to requests' do
|
50
|
+
stub_push
|
51
|
+
res = request.get '/slide?key=sekret&number=1'
|
52
|
+
|
53
|
+
assert { res.status == 204 }
|
54
|
+
assert { res.empty? }
|
55
|
+
|
56
|
+
assert_requested :post,
|
57
|
+
%r{http://api\.pusherapp\.com},
|
58
|
+
:body => JSON(:slide => '1')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'responds without pushing with an incorrect key' do
|
62
|
+
res = request.get '/slide?key=wrong'
|
63
|
+
|
64
|
+
assert { res.status == 204 }
|
65
|
+
assert { res.empty? }
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'overrides the default key' do
|
69
|
+
stub_push
|
70
|
+
res = request(:key => 'super-sekret').get '/slide?key=super-sekret&number=1'
|
71
|
+
|
72
|
+
assert { res.status == 204 }
|
73
|
+
assert { res.empty? }
|
74
|
+
|
75
|
+
assert_requested :post,
|
76
|
+
%r{http://api\.pusherapp\.com},
|
77
|
+
:body => JSON(:slide => '1')
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'uses the default key when nil' do
|
81
|
+
stub_push
|
82
|
+
res = request(:key => nil).get '/slide?key=sekret&number=1'
|
83
|
+
|
84
|
+
assert { res.status == 204 }
|
85
|
+
assert { res.empty? }
|
86
|
+
|
87
|
+
assert_requested :post,
|
88
|
+
%r{http://api\.pusherapp\.com},
|
89
|
+
:body => JSON(:slide => '1')
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: altum
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Larry Marburger
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-08-30 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: pusher
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rack
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0"
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: webmock
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: wrong
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id004
|
59
|
+
description: Present remotely
|
60
|
+
email:
|
61
|
+
- larry@marburger.cc
|
62
|
+
executables: []
|
63
|
+
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files: []
|
67
|
+
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- Gemfile
|
71
|
+
- README
|
72
|
+
- Rakefile
|
73
|
+
- altum.gemspec
|
74
|
+
- altum.js
|
75
|
+
- lib/altum.rb
|
76
|
+
- lib/altum/version.rb
|
77
|
+
- spec/altum_spec.rb
|
78
|
+
homepage: http://lmarburger.github.com/altum/
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: "0"
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Altum uses the magic of Pusher and websockets to drive a ShowOff presentation remotely. The simplest tool when you need to walk through a deck on a conference call.
|
105
|
+
test_files:
|
106
|
+
- spec/altum_spec.rb
|