sinatra_websocket_template 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: 553b00029fe8cceb8e255ac5f16a9c132c7f878d
4
+ data.tar.gz: eca78352ae22a0f5ded593b779fcb5aa8f379079
5
+ SHA512:
6
+ metadata.gz: caaa07419335bc28128f28f108a4161e2227e7a36a748aab81294417ebb4b8c669766f3f65938ba34335c05560255c259244fb32a0f82aa328f737a347024a1a
7
+ data.tar.gz: f5c746096767192a4d1db796cd8c661a1dae89857d929a4e9f3e2b6cd6c3262507ca4f51182b4e09942e50142289015de562a124d1dbe88adc40cca85efc62d9
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sinatra_websocket_template.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 kyoendo
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.
@@ -0,0 +1,33 @@
1
+ # SinatraWebsocketTemplate
2
+
3
+ `SinatraWebsocketTemplate` is for generating a skeleton of WebSocket application with Ruby(Sinatra)
4
+
5
+ A concept of the skeleton code is inspired by the following article:
6
+
7
+ > [Using WebSockets on Heroku with Ruby | Heroku Dev Center](https://devcenter.heroku.com/articles/ruby-websockets "Using WebSockets on Heroku with Ruby | Heroku Dev Center")
8
+
9
+ ## Installation
10
+
11
+ $ gem install sinatra_websocket_template
12
+
13
+ ## Usage
14
+
15
+ 4 steps to run a skeleton demo application;
16
+
17
+ $ sinatra_websocket_template new YOUR_PROJECT_NAME
18
+
19
+ $ cd YOUR_PROJECT_NAME
20
+
21
+ $ bundle install
22
+
23
+ $ bundle exec foreman start
24
+
25
+ Open http://localhost:5000 to review it, then modify it as you like.
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sinatra_websocket_template'
4
+
5
+ SinatraWebsocketTemplate::CLI.start(ARGV)
@@ -0,0 +1,7 @@
1
+ %w(version cli).each do |lib|
2
+ require "sinatra_websocket_template/#{lib}"
3
+ end
4
+
5
+ module SinatraWebsocketTemplate
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,74 @@
1
+ require 'thor'
2
+ require 'fileutils'
3
+
4
+ module SinatraWebsocketTemplate
5
+ class CLI < Thor
6
+ include Thor::Actions
7
+
8
+ def self.source_root
9
+ File.join(__dir__, 'templates')
10
+ end
11
+
12
+ desc "new PROJECT", "Creates a skeleton for your project"
13
+ option :dir, aliases:"-d", default:Dir.pwd, banner:"Specify a target directory for your project."
14
+ option :test, aliases:"-t", lazy_default:"rspec", banner:"Generate a test directory(default: rspec)."
15
+ option :bin, aliases:"-b", type: :boolean, default:false, banner:"Generate a binary."
16
+ def new(project_name)
17
+ target = File.join(options[:dir], project_name)
18
+ opts = {
19
+ module_name: project_name.split('_').map(&:capitalize).join,
20
+ namespaced_path: project_name
21
+ }
22
+
23
+ template("project/Procfile.tt", File.join(target, "Procfile"))
24
+ template("project/config.ru.tt", File.join(target, "config.ru"), opts)
25
+ lib_path = File.join(target, "lib")
26
+ template("project/lib/app.rb.tt", File.join(lib_path, "app.rb"), opts)
27
+ template("project/lib/views/index.haml.tt", File.join(lib_path, "views", "index.haml"), opts)
28
+ template("project/lib/public/css/main.css.tt", File.join(lib_path, "public", "css", "main.css"))
29
+ template("project/lib/public/js/application.js.tt", File.join(lib_path, "public", "js", "application.js"))
30
+ template("project/lib/project/backend.rb.tt", File.join(lib_path, project_name, "backend.rb"), opts)
31
+
32
+ execute_and_edit_bundle_gem(project_name, options)
33
+ end
34
+
35
+ desc "version", "Prints the SinatraWebsocketTemplate's version"
36
+ def version
37
+ puts "SinatraWebsocketTemplate version #{SinatraWebsocketTemplate::VERSION}"
38
+ end
39
+ map %w(-v --version) => :version
40
+
41
+ no_commands do
42
+ def execute_and_edit_bundle_gem(project_name, options)
43
+ dir = options[:dir]
44
+ opts = %i(test bin).map do |k|
45
+ "--#{k}=#{options[k]}" if options[k]
46
+ end.join(" ")
47
+
48
+ FileUtils.mkdir_p(dir)
49
+ Dir.chdir(dir) { system("bundle gem #{project_name} #{opts}") }
50
+ gemspec = File.join(dir, project_name, "#{project_name}.gemspec")
51
+ edit_gemspec(gemspec)
52
+ rescue => e
53
+ abort "Execute 'bundle gem' failed: #{e.message}"
54
+ end
55
+
56
+ def edit_gemspec(file)
57
+ content = File.read(file)
58
+ content.sub!(/^end\n$/, '')
59
+ content.concat(<<-EOS)
60
+ spec.add_development_dependency "foreman"
61
+
62
+ spec.add_dependency "faye-websocket"
63
+ spec.add_dependency "puma"
64
+ spec.add_dependency "sinatra"
65
+ spec.add_dependency "haml"
66
+
67
+ spec.required_ruby_version = ">= 2.0.0"
68
+ end
69
+ EOS
70
+ File.write(file, content)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1 @@
1
+ web: bundle exec puma -p $PORT
@@ -0,0 +1,6 @@
1
+ require 'app'
2
+ require '<%=config[:namespaced_path]%>/backend'
3
+
4
+ use <%=config[:module_name]%>::Backend
5
+
6
+ run <%=config[:module_name]%>::App
@@ -0,0 +1,10 @@
1
+ require 'sinatra/base'
2
+ require 'haml'
3
+
4
+ module <%=config[:module_name]%>
5
+ class App < Sinatra::Base
6
+ get "/" do
7
+ haml :index
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ require 'faye/websocket'
2
+ require 'json'
3
+
4
+ module <%=config[:module_name]%>
5
+ class Backend
6
+ KEEPALIVE_TIME = 15
7
+ def initialize(app)
8
+ @app = app
9
+ @clients = []
10
+ end
11
+
12
+ def call(env)
13
+ if Faye::WebSocket.websocket?(env)
14
+ ws = Faye::WebSocket.new(env, nil, ping: KEEPALIVE_TIME)
15
+
16
+ ws.on :open do |event|
17
+ p [:open, ws.object_id]
18
+ @clients << ws
19
+ ws.send({ you: ws.object_id }.to_json)
20
+ @clients.each do |client|
21
+ client.send({ count: @clients.size }.to_json)
22
+ end
23
+ end
24
+
25
+ ws.on :message do |event|
26
+ p [:message, event.data]
27
+ @clients.each { |client| client.send event.data }
28
+ end
29
+
30
+ ws.on :close do |event|
31
+ p [:close, ws.object_id, event.code]
32
+ @clients.delete(ws)
33
+ @clients.each do |client|
34
+ client.send({ count: @clients.size }.to_json)
35
+ end
36
+ ws = nil
37
+ end
38
+ ws.rack_response
39
+ else
40
+ @app.call(env)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ #count-button {
2
+ width: 100px;
3
+ }
4
+
5
+ .message {
6
+ color: orange;
7
+ }
8
+
9
+ .user-id {
10
+ color: green;
11
+ }
12
+
13
+ #user-counter {
14
+ border: none;
15
+ color: #FC0;
16
+ font-size: 16pt;
17
+ width: 50px;
18
+ text-align: right;
19
+ }
@@ -0,0 +1,28 @@
1
+ function counterRefresh (count) {
2
+ $("#user-counter").val(count);
3
+ }
4
+
5
+ function appendMessage (userid, message) {
6
+ $("#message-box").append("<div class='message'><span class='user-id'>" + userid + ":</span> " + message + "</div>");
7
+ }
8
+
9
+ $("#count-button").click(function(event) {
10
+ var text = this.innerHTML;
11
+ var data = JSON.stringify({ userid: myid, text: text });
12
+ ws.send(data);
13
+ });
14
+
15
+ var myid;
16
+
17
+ var ws = new WebSocket(location.origin.replace(/^http/, 'ws'));
18
+
19
+ ws.onmessage = function(msg) {
20
+ var data = JSON.parse(msg.data);
21
+ if (data.you) { myid = data.you; }
22
+ else if (data.text) {
23
+ var id;
24
+ myid==data.userid ? id = 'my-message' : id = data.userid;
25
+ appendMessage(id, data.text);
26
+ }
27
+ else if (data.count) { counterRefresh(data.count); }
28
+ }
@@ -0,0 +1,20 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %meta{charset:'utf-8'}
5
+ %meta{name:'viewport', content:'width=device-width, initial-scale=1.0'}
6
+ %title <%=config[:module_name]%>
7
+ %link{rel:'stylesheet', href:'css/main.css'}
8
+ %body
9
+ %header
10
+ %input#user-counter{type:"text", disable:"disable", value:0}
11
+ %label{for:"user-counter"} Users
12
+
13
+ .container
14
+ %button#count-button Hello!
15
+ #message-box
16
+
17
+ %footer
18
+
19
+ %script{src:'//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', type:'text/javascript'}
20
+ %script{src:'js/application.js', type:'text/javascript'}
@@ -0,0 +1,3 @@
1
+ module SinatraWebsocketTemplate
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sinatra_websocket_template/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sinatra_websocket_template"
8
+ spec.version = SinatraWebsocketTemplate::VERSION
9
+ spec.authors = ["kyoendo"]
10
+ spec.email = ["postagie@gmail.com"]
11
+ spec.description = %q{Generate a skeleton of WebSocket application with Ruby(Sinatra)}
12
+ spec.summary = %q{Generate a skeleton of WebSocket application with Ruby(Sinatra)}
13
+ spec.homepage = "https://github.com/melborne/sinatra-websocket-template"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = ">= 2.0.0"
22
+
23
+ spec.add_dependency "thor"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'pathname'
3
+ require 'stringio'
4
+
5
+ describe SinatraWebsocketTemplate::CLI do
6
+ before(:each) do
7
+ @tmp_path = File.join(Dir.pwd, "tmp")
8
+ @project_name = "project_a"
9
+ @project = Pathname.new(File.join @tmp_path, @project_name)
10
+ $stdout = StringIO.new
11
+ end
12
+
13
+ after(:each) do
14
+ FileUtils.rm_r(@tmp_path)
15
+ $stdout = STDOUT
16
+ end
17
+
18
+ describe '#new' do
19
+ context 'without bundler gem options' do
20
+ it 'creates a skelton project' do
21
+ described_class.start(['new', @project_name, '--dir', @tmp_path])
22
+ expect(@project.join("Procfile")).to exist
23
+
24
+ configru = @project.join("config.ru")
25
+ expect(configru).to exist
26
+ expect(configru.read).to match /project_a\/backend.*ProjectA::App/m
27
+
28
+ apprb = @project.join("lib", "app.rb")
29
+ expect(apprb).to exist
30
+ expect(apprb.read).to match /module ProjectA/
31
+
32
+ indexhaml = @project.join("lib", "views", "index.haml")
33
+ expect(indexhaml).to exist
34
+ expect(indexhaml.read).to match /%title ProjectA/
35
+
36
+ expect(@project.join("lib", "public", "css", "main.css")).to exist
37
+ expect(@project.join("lib", "public", "js", "application.js")).to exist
38
+ expect(@project.join("lib", "project_a", "backend.rb")).to exist
39
+
40
+ # created by 'bundle gem command'
41
+ expect(@project.join("Gemfile")).to exist
42
+ expect(@project.join("lib", "project_a.rb")).to exist
43
+
44
+ gemspec = @project.join("project_a.gemspec")
45
+ expect(gemspec).to exist
46
+ expect(gemspec.read).to match /spec\.add_dependency.*faye-websocket.*puma.*sinatra.*haml/m
47
+ end
48
+ end
49
+
50
+ context 'with bundler gem options' do
51
+ it 'create a skelton with a binary and spec files' do
52
+ described_class.start(['new', @project_name, '--dir', @tmp_path, '-bt'])
53
+ expect(@project.join("bin", "project_a")).to exist
54
+ expect(@project.join("spec", "project_a_spec.rb")).to exist
55
+ end
56
+
57
+ it 'create a skelton with minitest' do
58
+ described_class.start(['new', @project_name, '--dir', @tmp_path, '--test=minitest'])
59
+ expect(@project.join("test", "test_project_a.rb")).to exist
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe SinatraWebsocketTemplate do
4
+ it 'should have a version number' do
5
+ SinatraWebsocketTemplate::VERSION.should_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'sinatra_websocket_template'
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra_websocket_template
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - kyoendo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
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: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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: Generate a skeleton of WebSocket application with Ruby(Sinatra)
70
+ email:
71
+ - postagie@gmail.com
72
+ executables:
73
+ - sinatra_websocket_template
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - .rspec
79
+ - .travis.yml
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/sinatra_websocket_template
85
+ - lib/sinatra_websocket_template.rb
86
+ - lib/sinatra_websocket_template/cli.rb
87
+ - lib/sinatra_websocket_template/templates/project/Procfile.tt
88
+ - lib/sinatra_websocket_template/templates/project/config.ru.tt
89
+ - lib/sinatra_websocket_template/templates/project/lib/app.rb.tt
90
+ - lib/sinatra_websocket_template/templates/project/lib/project/backend.rb.tt
91
+ - lib/sinatra_websocket_template/templates/project/lib/public/css/main.css.tt
92
+ - lib/sinatra_websocket_template/templates/project/lib/public/js/application.js.tt
93
+ - lib/sinatra_websocket_template/templates/project/lib/views/index.haml.tt
94
+ - lib/sinatra_websocket_template/version.rb
95
+ - sinatra_websocket_template.gemspec
96
+ - spec/cli_spec.rb
97
+ - spec/sinatra_websocket_template_spec.rb
98
+ - spec/spec_helper.rb
99
+ homepage: https://github.com/melborne/sinatra-websocket-template
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: 2.0.0
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.1.11
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Generate a skeleton of WebSocket application with Ruby(Sinatra)
123
+ test_files:
124
+ - spec/cli_spec.rb
125
+ - spec/sinatra_websocket_template_spec.rb
126
+ - spec/spec_helper.rb
127
+ has_rdoc: