websocket-gui 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/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +143 -0
- data/Rakefile +69 -0
- data/examples/example.rb +30 -0
- data/examples/index.erb +63 -0
- data/lib/websocket-gui/base.rb +79 -0
- data/lib/websocket-gui/sinatra_wrapper.rb +18 -0
- data/lib/websocket-gui/version.rb +3 -0
- data/lib/websocket-gui.rb +10 -0
- data/spec/base_spec.rb +44 -0
- data/spec/spec_helper.rb +18 -0
- data/websocket-gui.gemspec +31 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0f9b2ada3cef153c8ebd85ff255e143068f21dcd
|
4
|
+
data.tar.gz: 0d95a12c9c9fdf239b5f9f4ca26d598766a600cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1ba9084cbfcd657ea4e3cda19fbf071ce5497925d2537ca5d219b30b7038eb4c225dfbe4efbb1a7fe753df9721953b8d110a4843fb2a5776e4aed2efe289fc8
|
7
|
+
data.tar.gz: 7bf16018e44381dded3b25ea882ed0155d9339b6bdc631ff832ec8c8078ae9e927ab04270d47150dfbbe2f8e0d031225c075e71be51a49207d4b8a7c5ccc05f5
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jason
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# Websocket Gui
|
2
|
+
This gem uses Sinatra, EventMachine, and Web Sockets to make it easy to use the browser as a GUI for Ruby apps that
|
3
|
+
would otherwise be stuck in the console.
|
4
|
+
|
5
|
+
|
6
|
+
## Using Websocket Gui
|
7
|
+
To use this gem, make a class that extends WebsocketGui::Base and a HTML/JS file to serve as the GUI.
|
8
|
+
|
9
|
+
|
10
|
+
### Configuration
|
11
|
+
The following configuration options are available:
|
12
|
+
:socket_port (8080)
|
13
|
+
:socket_host (127.0.0.1)
|
14
|
+
:http_port (3000)
|
15
|
+
:http_host (127.0.0.1)
|
16
|
+
:view (:index)
|
17
|
+
:tick_interval (nil)
|
18
|
+
|
19
|
+
The options can be set in several ways, each level overriding the previous:
|
20
|
+
1 In declaring your subclass of WebsocketGui::Base (like tick\_interval below)
|
21
|
+
1 By passing an options hash to the initializer
|
22
|
+
1 By passing an options hash to the run! method
|
23
|
+
|
24
|
+
|
25
|
+
### project-root/app.rb
|
26
|
+
require 'websocket-gui'
|
27
|
+
|
28
|
+
class App < WebsocketGui::Base
|
29
|
+
|
30
|
+
# specify the name of the file containing the HTML of the app (this is a single-page app)
|
31
|
+
# ex. Look in root directory for frontendfile.erb instead of index.erb (which is the default)
|
32
|
+
#view :frontendfile
|
33
|
+
|
34
|
+
# set the time (seconds) between calls to 'on_tick'
|
35
|
+
# if nil (default), on_tick will not fire
|
36
|
+
tick_interval 0.1
|
37
|
+
|
38
|
+
# code for the on_tick event
|
39
|
+
on_tick do |connected|
|
40
|
+
@tick_block.call(connected)
|
41
|
+
end
|
42
|
+
|
43
|
+
# code for the on_socket_open event
|
44
|
+
on_socket_open do |handshake|
|
45
|
+
socket_send "Welcome!!!"
|
46
|
+
puts "Client connection opened:"
|
47
|
+
puts "#{handshake.inspect}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# code for the on_socket_recv event
|
51
|
+
on_socket_recv do |msg|
|
52
|
+
puts "Received message from client: #{msg.strip}"
|
53
|
+
socket_send "I received your message: #{msg.strip}"
|
54
|
+
end
|
55
|
+
|
56
|
+
# code for the on_socket_close event
|
57
|
+
on_socket_close do
|
58
|
+
puts "Socket closed."
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# specify options in the constructor and/or the run method.
|
63
|
+
instance = App.new http_port: 3000, http_host: '127.0.0.1'
|
64
|
+
instance.run! socket_port: 8080, socket_host: '127.0.0.1'
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
### project-root/index.erb
|
69
|
+
|
70
|
+
<!doctype html>
|
71
|
+
<html>
|
72
|
+
<head>
|
73
|
+
<title>Test Web Sockets</title>
|
74
|
+
<meta charset="utf-8" />
|
75
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
76
|
+
</head>
|
77
|
+
|
78
|
+
<body>
|
79
|
+
<div id="connectedContainer" style="display:none;">
|
80
|
+
<textarea id="input"></textarea>
|
81
|
+
<input type="button" id="send" value="Send" />
|
82
|
+
|
83
|
+
<ul id="output"></ul>
|
84
|
+
<input type="button" id="disconnect" value="Disconnect" />
|
85
|
+
</div>
|
86
|
+
<div id="notConnectedContainer">
|
87
|
+
<input type="button" id="connect" value="Connect" />
|
88
|
+
</div>
|
89
|
+
<script type="text/javascript">
|
90
|
+
var socket;
|
91
|
+
var connect = function () {
|
92
|
+
socket = new WebSocket("ws://localhost:8080");
|
93
|
+
var writeMessage = function (msg) {
|
94
|
+
$("<li></li>").text (msg).appendTo ($("#output"));
|
95
|
+
};
|
96
|
+
socket.onmessage = function (evt) {
|
97
|
+
writeMessage (evt.data);
|
98
|
+
};
|
99
|
+
socket.onclose = function () {
|
100
|
+
writeMessage ("Socket Closed!");
|
101
|
+
$("#connectedContainer").hide ();
|
102
|
+
$("#notConnectedContainer").show();
|
103
|
+
$("#output li").remove ();
|
104
|
+
}
|
105
|
+
socket.onopen = function () {
|
106
|
+
writeMessage ("Socket Opened!");
|
107
|
+
$("#connectedContainer").show ();
|
108
|
+
$("#notConnectedContainer").hide ();
|
109
|
+
}
|
110
|
+
$("#send").on ('click', function () {
|
111
|
+
var input = $("#input");
|
112
|
+
if (input.val ())
|
113
|
+
{
|
114
|
+
socket.send(input.val ());
|
115
|
+
input.val ('');
|
116
|
+
}
|
117
|
+
});
|
118
|
+
}
|
119
|
+
$("#connect").on ('click', function () { connect (); } );
|
120
|
+
$("#disconnect").on ('click', function () { socket.close (); });
|
121
|
+
|
122
|
+
</script>
|
123
|
+
</body>
|
124
|
+
</html>
|
125
|
+
|
126
|
+
|
127
|
+
## file structure
|
128
|
+
project-root/
|
129
|
+
app.rb
|
130
|
+
index.erb
|
131
|
+
... (up to you)
|
132
|
+
|
133
|
+
|
134
|
+
## running the app (from the project dir)
|
135
|
+
$ ruby app.rb
|
136
|
+
|
137
|
+
This will start the socket server and sinatra, and launch a browser with your view.
|
138
|
+
|
139
|
+
|
140
|
+
## todo
|
141
|
+
* Create a small JS library that wraps the native websocket and makes it easy to post events to the server.
|
142
|
+
* Expand event handlers so you can write events like `on_start do |params|` instead of having to do parse raw strings and do everything in on\_socket\_recv
|
143
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
#################################################################################
|
7
|
+
#
|
8
|
+
# Some utilities to find out info about the package
|
9
|
+
#
|
10
|
+
#################################################################################
|
11
|
+
|
12
|
+
def name
|
13
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
14
|
+
end
|
15
|
+
|
16
|
+
def version
|
17
|
+
line = File.read("lib/#{name}/version.rb")[/^\s*VERSION\s*=\s*.*/]
|
18
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
19
|
+
end
|
20
|
+
|
21
|
+
def gemspec_file
|
22
|
+
"#{name}.gemspec"
|
23
|
+
end
|
24
|
+
|
25
|
+
def gem_file
|
26
|
+
"pkg/#{name}-#{version}.gem"
|
27
|
+
end
|
28
|
+
|
29
|
+
#################################################################################
|
30
|
+
#
|
31
|
+
# Tasks
|
32
|
+
#
|
33
|
+
#################################################################################
|
34
|
+
|
35
|
+
desc "Run the tests"
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rspec/core/rake_task'
|
39
|
+
RSpec::Core::RakeTask.new(:spec)
|
40
|
+
|
41
|
+
desc "Build gem locally"
|
42
|
+
task :build => :validate do
|
43
|
+
system "gem build #{name}.gemspec"
|
44
|
+
FileUtils.mkdir_p "pkg"
|
45
|
+
FileUtils.mv "#{name}-#{version}.gem", gem_file
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Publish the gem to rubygems.org"
|
49
|
+
task :publish => :build do
|
50
|
+
system "gem push #{gem_file}"
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Install gem locally"
|
54
|
+
task :install => :build do
|
55
|
+
system "gem install #{gem_file}"
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Validate #{gemspec_file}"
|
59
|
+
task :validate do
|
60
|
+
libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
|
61
|
+
unless libfiles.empty?
|
62
|
+
puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
|
63
|
+
exit!
|
64
|
+
end
|
65
|
+
unless Dir['VERSION*'].empty?
|
66
|
+
puts "A `VERSION` file at root level violates Gem best practices."
|
67
|
+
exit!
|
68
|
+
end
|
69
|
+
end
|
data/examples/example.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('../../lib/websocket-gui', __FILE__)
|
2
|
+
|
3
|
+
class ExampleWebSocketApp < WebsocketGui::Base
|
4
|
+
|
5
|
+
tick_interval 5
|
6
|
+
|
7
|
+
on_tick do |connected|
|
8
|
+
puts "Tick: " + (connected ? "connected" : "not connected")
|
9
|
+
socket_send "Tick"
|
10
|
+
end
|
11
|
+
|
12
|
+
on_socket_open do |handshake|
|
13
|
+
socket_send "Socket opened. Welcome!!!"
|
14
|
+
puts "Client connection opened.\n Handshake:\n #{handshake.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
on_socket_recv do |msg|
|
18
|
+
puts "Received message from client: #{msg.strip}"
|
19
|
+
socket_send "I received your message: #{msg.strip}"
|
20
|
+
end
|
21
|
+
|
22
|
+
on_socket_close do
|
23
|
+
puts "Socket closed."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if __FILE__ == $0
|
28
|
+
example = ExampleWebSocketApp.new
|
29
|
+
example.run!
|
30
|
+
end
|
data/examples/index.erb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<html>
|
4
|
+
|
5
|
+
<head>
|
6
|
+
<title>Test Web Sockets</title>
|
7
|
+
<meta charset="utf-8" />
|
8
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
9
|
+
<style type="text/css">
|
10
|
+
|
11
|
+
</style>
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body>
|
15
|
+
<div id="connectedContainer" style="display:none;">
|
16
|
+
<textarea id="input"></textarea>
|
17
|
+
<input type="button" id="send" value="Send" />
|
18
|
+
|
19
|
+
<ul id="output"></ul>
|
20
|
+
<input type="button" id="disconnect" value="Disconnect" />
|
21
|
+
</div>
|
22
|
+
<div id="notConnectedContainer">
|
23
|
+
<input type="button" id="connect" value="Connect" />
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<script type="text/javascript">
|
27
|
+
var socket;
|
28
|
+
var connect = function () {
|
29
|
+
socket = new WebSocket("ws://localhost:8080");
|
30
|
+
var writeMessage = function (msg) {
|
31
|
+
$("<li></li>").text (msg).appendTo ($("#output"));
|
32
|
+
};
|
33
|
+
socket.onmessage = function (evt) {
|
34
|
+
writeMessage (evt.data);
|
35
|
+
};
|
36
|
+
socket.onclose = function () {
|
37
|
+
writeMessage ("Socket Closed!");
|
38
|
+
$("#connectedContainer").hide ();
|
39
|
+
$("#notConnectedContainer").show();
|
40
|
+
$("#output li").remove ();
|
41
|
+
}
|
42
|
+
socket.onopen = function () {
|
43
|
+
writeMessage ("Socket Opened!");
|
44
|
+
$("#connectedContainer").show ();
|
45
|
+
$("#notConnectedContainer").hide ();
|
46
|
+
}
|
47
|
+
$("#send").on ('click', function () {
|
48
|
+
var input = $("#input");
|
49
|
+
if (input.val ())
|
50
|
+
{
|
51
|
+
socket.send(input.val ());
|
52
|
+
input.val ('');
|
53
|
+
}
|
54
|
+
});
|
55
|
+
}
|
56
|
+
|
57
|
+
$("#connect").on ('click', function () { connect (); } );
|
58
|
+
$("#disconnect").on ('click', function () { socket.close (); });
|
59
|
+
|
60
|
+
</script>
|
61
|
+
</body>
|
62
|
+
|
63
|
+
</html>
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module WebsocketGui
|
2
|
+
|
3
|
+
class Base
|
4
|
+
|
5
|
+
# class-level config, so you can wire your settings into your class
|
6
|
+
# These can also be provided when calling run!
|
7
|
+
@@config = {
|
8
|
+
socket_port: 8080,
|
9
|
+
socket_host: '127.0.0.1',
|
10
|
+
http_port: 3000,
|
11
|
+
http_host: '127.0.0.1',
|
12
|
+
tick_interval: nil,
|
13
|
+
view: :index,
|
14
|
+
}
|
15
|
+
def self.method_missing(method, *args, &block)
|
16
|
+
if block_given?
|
17
|
+
@@config[method] = block
|
18
|
+
else
|
19
|
+
@@config[method] = args.first
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :config
|
24
|
+
|
25
|
+
def initialize(config = {})
|
26
|
+
@config = @@config.merge(config)
|
27
|
+
end
|
28
|
+
|
29
|
+
# start the socket server and the web server, and launch a browser to fetch the view from the web server
|
30
|
+
def run!(runtime_config = {})
|
31
|
+
@config.merge! runtime_config
|
32
|
+
|
33
|
+
EM.run do
|
34
|
+
if @config[:tick_interval]
|
35
|
+
EM.add_periodic_timer(@config[:tick_interval]) do
|
36
|
+
socket_trigger(:on_tick, @socket_connected)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
EventMachine::WebSocket.run(host: @config[:socket_host], port: @config[:socket_port]) do |socket|
|
41
|
+
@socket_active = socket
|
42
|
+
socket.onopen do |handshake|
|
43
|
+
@socket_connected = true
|
44
|
+
socket_trigger(:on_socket_open, handshake)
|
45
|
+
end
|
46
|
+
|
47
|
+
socket.onmessage do |msg|
|
48
|
+
socket_trigger(:on_socket_recv, msg)
|
49
|
+
end
|
50
|
+
|
51
|
+
socket.onclose do
|
52
|
+
socket_trigger(:on_socket_close)
|
53
|
+
@socket_connected = false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Launchy.open("http://#{@config[:http_host]}:#{@config[:http_port]}/")
|
58
|
+
WebsocketGui::SinatraWrapper.view_path = @config[:view]
|
59
|
+
WebsocketGui::SinatraWrapper.run!(
|
60
|
+
port: @config[:http_port],
|
61
|
+
bind: @config[:http_host])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def socket_send(msg)
|
66
|
+
@socket_active.send msg if @socket_connected
|
67
|
+
end
|
68
|
+
|
69
|
+
def socket_close
|
70
|
+
@socket_active.stop if @socket_connected
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def socket_trigger(method, *args)
|
76
|
+
self.instance_exec(*args, &@config[method]) if @config[method].kind_of? Proc
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module WebsocketGui
|
2
|
+
class SinatraWrapper < Sinatra::Base
|
3
|
+
|
4
|
+
set :views, './'
|
5
|
+
|
6
|
+
get '/' do
|
7
|
+
erb self.class.view_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.view_path
|
11
|
+
@view_path || :index
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.view_path=(view_path)
|
15
|
+
@view_path = view_path.to_sym
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# the example loads dependencies AND gives us an example class to test
|
2
|
+
require File.expand_path('../../examples/example', __FILE__)
|
3
|
+
|
4
|
+
describe ExampleWebSocketApp do
|
5
|
+
|
6
|
+
it { should respond_to(:run!) }
|
7
|
+
it { should respond_to(:socket_send) }
|
8
|
+
it { should respond_to(:socket_close) }
|
9
|
+
its(:config) { should be_an_instance_of(Hash) }
|
10
|
+
|
11
|
+
context "override Base defaults" do
|
12
|
+
let(:example) {
|
13
|
+
ExampleWebSocketApp.new(http_port: 80, http_host: "localhost")
|
14
|
+
}
|
15
|
+
let(:config) { example.config }
|
16
|
+
|
17
|
+
it "has defaults inherited from Base" do
|
18
|
+
config[:socket_port].should equal(8080)
|
19
|
+
config[:socket_host].should match('127.0.0.1')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "overrides defaults in subclass definition" do
|
23
|
+
config[:tick_interval].should equal(5)
|
24
|
+
config[:on_tick].should be_a_kind_of(Proc)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "overrides defaults in constructor" do
|
28
|
+
config[:http_port].should equal(80)
|
29
|
+
config[:http_host].should match('localhost')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "override subclass defaults" do
|
34
|
+
let(:example) {
|
35
|
+
ExampleWebSocketApp.new(tick_interval: 1)
|
36
|
+
}
|
37
|
+
let(:config) { example.config }
|
38
|
+
|
39
|
+
it "overrides already overridden defaults in constructor" do
|
40
|
+
config[:tick_interval].should equal(1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'websocket-gui/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "websocket-gui"
|
8
|
+
spec.version = WebsocketGui::VERSION
|
9
|
+
spec.authors = ["Jason Pollentier"]
|
10
|
+
spec.email = ["pollentj@gmail.com"]
|
11
|
+
spec.description = %q{Use Sinatra, Websockets, and EventMachine to create
|
12
|
+
an event-based GUI for Ruby projects that would otherwise be stuck in the console.
|
13
|
+
}
|
14
|
+
spec.summary = %q{Use the browser as a GUI for local Ruby apps.}
|
15
|
+
spec.homepage = ""
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.required_ruby_version = '~> 2.0'
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_runtime_dependency 'em-websocket', '~> 0.5.0'
|
28
|
+
spec.add_runtime_dependency 'sinatra', '~> 1.4.3'
|
29
|
+
spec.add_runtime_dependency 'thin', '>= 1.5.1'
|
30
|
+
spec.add_runtime_dependency 'launchy', '~> 2.3.0'
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: websocket-gui
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Pollentier
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-05 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: rspec
|
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: em-websocket
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.5.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.5.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sinatra
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.4.3
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.4.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: thin
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.5.1
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.5.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: launchy
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.3.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.3.0
|
111
|
+
description: |
|
112
|
+
Use Sinatra, Websockets, and EventMachine to create
|
113
|
+
an event-based GUI for Ruby projects that would otherwise be stuck in the console.
|
114
|
+
email:
|
115
|
+
- pollentj@gmail.com
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- .gitignore
|
121
|
+
- .rspec
|
122
|
+
- Gemfile
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- examples/example.rb
|
127
|
+
- examples/index.erb
|
128
|
+
- lib/websocket-gui.rb
|
129
|
+
- lib/websocket-gui/base.rb
|
130
|
+
- lib/websocket-gui/sinatra_wrapper.rb
|
131
|
+
- lib/websocket-gui/version.rb
|
132
|
+
- spec/base_spec.rb
|
133
|
+
- spec/spec_helper.rb
|
134
|
+
- websocket-gui.gemspec
|
135
|
+
homepage: ''
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ~>
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '2.0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.0.7
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: Use the browser as a GUI for local Ruby apps.
|
159
|
+
test_files:
|
160
|
+
- spec/base_spec.rb
|
161
|
+
- spec/spec_helper.rb
|