sombrero 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Rakefile +1 -2
  4. data/app/.gitignore +6 -0
  5. data/app/.pryrc +1 -0
  6. data/app/Gemfile +6 -0
  7. data/app/Rakefile +1 -0
  8. data/app/base/base_controller.rb +3 -0
  9. data/app/base/boot.rb +2 -0
  10. data/app/base/helpers/application_helpers.rb +1 -0
  11. data/app/base/load_controllers.rb +2 -0
  12. data/app/base/rtcp_controller.rb +22 -0
  13. data/app/config/config.rb +11 -0
  14. data/app/config/config.yml +11 -0
  15. data/app/config/env/development.yml +0 -0
  16. data/app/config/env/production.yml +0 -0
  17. data/app/config/env/stage.yml +0 -0
  18. data/app/config/env/test.yml +0 -0
  19. data/app/config.ru +3 -0
  20. data/app/core/Gemfile +5 -0
  21. data/app/core/boot.rb +17 -0
  22. data/app/core/client/activity_observer.coffee +37 -0
  23. data/app/core/client/api.coffee +248 -0
  24. data/app/core/client/channels.coffee +37 -0
  25. data/app/core/client/load.coffee +20 -0
  26. data/app/core/client/page.coffee +68 -0
  27. data/app/core/client/polyfills/array.compact.coffee +4 -0
  28. data/app/core/client/polyfills/array.compact_join.coffee +4 -0
  29. data/app/core/client/polyfills/number.to_money.coffee +3 -0
  30. data/app/core/client/polyfills/string.capitalize.coffee +4 -0
  31. data/app/core/client/polyfills/string.strip.coffee +5 -0
  32. data/app/core/client/polyfills.coffee +6 -0
  33. data/app/core/client/render.coffee +57 -0
  34. data/app/core/client/util/alert.coffee +50 -0
  35. data/app/core/client/util/datetime.coffee +47 -0
  36. data/app/core/client/util.coffee +38 -0
  37. data/app/core/generate_controllers_map.rb +4 -0
  38. data/app/core/generate_webpack_setup.rb +4 -0
  39. data/app/core/load.rb +5 -0
  40. data/app/core/load_controllers.rb +16 -0
  41. data/app/package.json +5 -0
  42. data/app/webpack.config.js +51 -0
  43. data/bin/sombrero +5 -0
  44. data/docker/Dockerfile +5 -0
  45. data/docker/base/Dockerfile +3 -0
  46. data/docker/base/build +10 -0
  47. data/docker/base/build.sh +25 -0
  48. data/docker/cleanup +7 -0
  49. data/docker/run +68 -0
  50. data/docker/skel/build.sh +1 -0
  51. data/docker/skel/config.yml +24 -0
  52. data/docker/skel/prepare_build.sh +5 -0
  53. data/docker/skel/start.sh +1 -0
  54. data/docker/start +7 -0
  55. data/lib/sombrero/{version.rb → app.rb} +3 -1
  56. data/lib/sombrero/base_controller.rb +5 -0
  57. data/lib/sombrero/cli/app/install.rb +38 -0
  58. data/lib/sombrero/cli/app/update.rb +20 -0
  59. data/lib/sombrero/cli/app.rb +10 -0
  60. data/lib/sombrero/cli/docker/build.rb +170 -0
  61. data/lib/sombrero/cli/docker/install.rb +23 -0
  62. data/lib/sombrero/cli/docker.rb +14 -0
  63. data/lib/sombrero/cli.rb +128 -0
  64. data/lib/sombrero/rtcp_controller.rb +93 -0
  65. data/lib/sombrero.rb +110 -2
  66. data/sombrero.gemspec +6 -1
  67. metadata +91 -4
@@ -0,0 +1,23 @@
1
+ module Sombrero
2
+ class CLI
3
+ module Docker
4
+ class Install
5
+ include InstallHelpers
6
+
7
+ def initialize dir
8
+ ensure_dirname_exists(dir)
9
+ assert_installable_dir(dir)
10
+ install(dir)
11
+ end
12
+
13
+ def install dir
14
+ src = dir.to_path == '.' ? BASE_DIR.to_path + '/skel/.' : BASE_DIR / 'skel'
15
+ FileUtils.cp_r(src, dir)
16
+ FileUtils.chmod('+x', dir / PREPARE_BUILD_FILE)
17
+ puts "Done. All files installed into #{dir}"
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ module Sombrero
2
+ class CLI
3
+ module Docker
4
+ BASE_DIR = (Sombrero::BASE_DIR / 'docker').freeze
5
+ CONFIG_FILE = './config.yml'.freeze
6
+ START_FILE = './start.sh'.freeze
7
+ PREPARE_BUILD_FILE = './prepare_build.sh'.freeze
8
+ BUILD_FILE = './build.sh'.freeze
9
+ end
10
+ end
11
+ end
12
+
13
+ require 'sombrero/cli/docker/install'
14
+ require 'sombrero/cli/docker/build'
@@ -0,0 +1,128 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'yaml'
4
+ require 'pty'
5
+
6
+ module Sombrero
7
+ BASE_DIR = Pathname.new(File.expand_path('../../..', __FILE__)).freeze
8
+
9
+ class CLI
10
+ module InstallHelpers
11
+
12
+ def ensure_dirname_exists dir
13
+ FileUtils.mkdir_p(File.dirname(dir))
14
+ end
15
+
16
+ def assert_installable_dir dir
17
+ if dir.to_path == '.'
18
+ assert_empty_dir(dir)
19
+ else
20
+ assert_dir_does_not_exists(dir)
21
+ end
22
+ end
23
+
24
+ def assert_empty_dir dir
25
+ return if Dir[dir / '*'].empty?
26
+ puts "", "\t::: #{dir} should be empty :::", ""
27
+ exit 1
28
+ end
29
+
30
+ def assert_dir_does_not_exists dir
31
+ return unless File.exists?(dir)
32
+ puts "", "\t::: #{dir} already exists :::", ""
33
+ exit 1
34
+ end
35
+ end
36
+
37
+ def initialize args
38
+ case command = args[0]
39
+ when 'a', 'app'
40
+ app(args)
41
+ when 'd', 'docker'
42
+ docker(args)
43
+ else
44
+ unknown_command_error!(command)
45
+ end
46
+ end
47
+
48
+ def app args
49
+ missing_destination_error! unless args[2]
50
+ dir = Pathname.new(args[2])
51
+
52
+ case instruction = args[1]
53
+ when 'i', 'install'
54
+ App::Install.new(dir, extract_namespace(args))
55
+ when 'u', 'update'
56
+ App::Update.new(dir, args)
57
+ else
58
+ unknown_instruction_error!(instruction, 'install or (i)', 'update or (u)')
59
+ end
60
+ end
61
+
62
+ def extract_namespace args
63
+ return unless index = args.index('-n')
64
+ return unless namespace = args[index + 1]
65
+ if namespace =~ /::/
66
+ puts "", "\t::: Nested namespaces not supported :::", ""
67
+ exit 1
68
+ end
69
+ if namespace =~ /\W/
70
+ puts "", "\t::: Namespace may contain only alphanumerics :::", ""
71
+ exit 1
72
+ end
73
+ unless namespace =~ /\A[A-Z]/
74
+ puts "", "\t::: Namespace should start with a capital letter :::", ""
75
+ exit 1
76
+ end
77
+ namespace
78
+ end
79
+
80
+ def docker args
81
+ missing_destination_error! unless args[2]
82
+ dir = Pathname.new(args[2])
83
+
84
+ case instruction = args[1]
85
+ when 'i', 'install'
86
+ Docker::Install.new(dir)
87
+ when 'b', 'build'
88
+ Docker::Build.new(dir, args)
89
+ else
90
+ unknown_instruction_error!(instruction, 'install or (i)', 'build or (b)')
91
+ end
92
+ end
93
+
94
+ def missing_destination_error!
95
+ puts "", "\t::: Please provide a directory to install files into :::", ""
96
+ exit 1
97
+ end
98
+
99
+ def unknown_command_error! command, *available_commands
100
+ puts "", "\t::: Unknown command #{command}. Use one of #{available_commands*', '} :::", ""
101
+ exit 1
102
+ end
103
+
104
+ def unknown_instruction_error! instruction, *available_instructions
105
+ puts "", "\t::: Unknown instruction #{instruction}. Use one of #{available_instructions*', '} :::", ""
106
+ exit 1
107
+ end
108
+
109
+ def self.run cmd
110
+ puts "", "$ #{cmd}"
111
+ PTY.spawn cmd do |r, w, pid|
112
+ begin
113
+ r.sync
114
+ r.each_char do |char|
115
+ print(char)
116
+ end
117
+ rescue Errno::EIO => e
118
+ # simply ignoring this
119
+ ensure
120
+ Process.wait(pid)
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ require 'sombrero/cli/app'
128
+ require 'sombrero/cli/docker'
@@ -0,0 +1,93 @@
1
+ # dirty hack until this is merged and released
2
+ # github.com/ngauthier/tubesock/pull/50
3
+ class Tubesock
4
+ def close!
5
+ if @socket.respond_to?(:closed?)
6
+ @socket.close unless @socket.closed?
7
+ else
8
+ @socket.close
9
+ end
10
+ end
11
+ end
12
+
13
+ module Sombrero
14
+ class RTCPController < BaseController
15
+ attr_reader :socket
16
+
17
+ def get
18
+ return unless websocket?
19
+
20
+ @router = RocketIO::Router.new(*RocketIO.controllers)
21
+
22
+ @socket = Tubesock.hijack(env)
23
+ @socket.onopen(&method(:on_open))
24
+ @socket.onmessage(&method(:on_message))
25
+ @socket.onclose(&method(:on_close))
26
+ @socket.listen
27
+
28
+ halt websocket_response
29
+ end
30
+
31
+ private
32
+
33
+ def on_open
34
+ connected
35
+ write(serial: 0, data: initialization_data.update(__initialization_data__))
36
+ end
37
+
38
+ def __initialization_data__
39
+ {
40
+ app_url: Cfg.app[:url][RocketIO.environment] || Cfg.app[:url][:development]
41
+ }
42
+ end
43
+
44
+ def on_message msg
45
+
46
+ msg = indifferent_params(JSON.parse(msg))
47
+ if controller = resolve_controller(msg[:controller])
48
+ status, _, body = call_controller(controller, msg[:method], msg[:arguments])
49
+ if status == 200
50
+ write(serial: msg[:serial], data: body) if msg[:reply]
51
+ return
52
+ end
53
+ else
54
+ body = '404: Not Found'
55
+ end
56
+
57
+ error = if body.is_a?(Array) && body.size == 1
58
+ body[0]
59
+ else
60
+ body
61
+ end
62
+
63
+ if msg && msg[:serial]
64
+ write(serial: msg[:serial], data: {__rtcp_error__: error})
65
+ else
66
+ write(error: error)
67
+ end
68
+
69
+ rescue Errno::EPIPE => e
70
+ close
71
+ rescue Exception => e
72
+ __error__(500, e)
73
+ end
74
+
75
+ def on_close
76
+ @socket.close! if @socket
77
+ @socket, @user, @router = nil
78
+ disconnected
79
+ end
80
+
81
+ def resolve_controller url
82
+ @router.resolve_path(url)[0]
83
+ end
84
+
85
+ def call_controller controller, method, arguments
86
+ controller.initialize_controller(method, arguments).call(env.merge(rtcp_env))
87
+ end
88
+
89
+ def write data
90
+ @socket.send_data(data.to_json)
91
+ end
92
+ end
93
+ end
data/lib/sombrero.rb CHANGED
@@ -1,5 +1,113 @@
1
- require "sombrero/version"
1
+ require 'rocketio'
2
2
 
3
3
  module Sombrero
4
- # Your code goes here...
4
+ extend self
5
+
6
+ def load_config dir, env = RocketIO.environment
7
+
8
+ config = load_config_file("#{dir}/config.yml")
9
+ config.update(load_config_file("#{dir}/env/#{env}.yml"))
10
+ config[:environment] = env.to_s.freeze
11
+
12
+ Dir["#{dir}/**/*.yml"].each do |file|
13
+ next if File.dirname(file) == './env'
14
+
15
+ key = File.basename(file, '.yml')
16
+ next if key == 'config' || key == 'sombrero'
17
+
18
+ key_config = load_config_file(file)
19
+ key_config_keys = key_config.keys.map(&:to_s)
20
+
21
+ config[key] = if key_config_keys.include?(env.to_s)
22
+ # current environment found, use it
23
+ key_config[env]
24
+ else
25
+ if RocketIO::ENVIRONMENTS.keys.find {|k| key_config_keys.include?(k)}
26
+ # there are some environment(s), but no current one so set current environment to nil
27
+ nil
28
+ else
29
+ # there are no environments, so this config is available on any environment
30
+ key_config
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ def config.method_missing key
37
+ self[key]
38
+ end
39
+
40
+ config
41
+ end
42
+
43
+ def load_config_file file
44
+ RocketIO.indifferent_params(YAML.load(File.read(file)) || {})
45
+ end
46
+
47
+ def generate_controllers_map dir
48
+ File.open File.expand_path('controllers.json', dir), 'w' do |f|
49
+ f << controllers_map(dir).to_json
50
+ end
51
+ end
52
+
53
+ def controllers_map dir
54
+ path_to_api = File.expand_path('base/api', dir)
55
+ RocketIO.controllers.each_with_object([]) do |controller,o|
56
+ next unless controller.dirname[path_to_api]
57
+
58
+ o << {
59
+ path: controller.dirname.sub(path_to_api, '').gsub(/\A\/|\/\Z/, ''),
60
+ url: controller.url,
61
+ url_pattern: url_pattern(controller),
62
+ name: controller.name.gsub('::', '__'),
63
+ api: controller.api
64
+ }
65
+ end
66
+ end
67
+
68
+ def generate_webpack_setup dir
69
+ config = load_config_file(File.expand_path('config/config.yml', dir))
70
+
71
+ entries = controllers_map(dir).each_with_object({}) do |controller,o|
72
+
73
+ next unless entry = %w[
74
+ ./base/api/%s/client.js
75
+ ./base/api/%s/client.coffee
76
+ ].map {|p| p % controller[:path]}.find {|f| File.file?(File.expand_path(f, dir))}
77
+
78
+ o[controller[:path]] = File.join('./base/api', controller[:path], File.basename(entry))
79
+ end
80
+
81
+ if core = %w[
82
+ ./base/core.js
83
+ ./base/core.coffee
84
+ ].find {|f| File.file?(File.expand_path(f, dir))}
85
+ entries[:core] = core
86
+ end
87
+
88
+ File.open File.expand_path('webpack_setup.json', dir), 'w' do |f|
89
+ f << {
90
+ path: config[:app][:dir],
91
+ url: config[:app][:url][:development],
92
+ entries: entries
93
+ }.to_json
94
+ end
95
+ end
96
+
97
+ def url_pattern controller
98
+ controller.url *controller.instance_method(:get).parameters.each_with_object([]) {|param,o|
99
+ pattern = if param[0] == :rest
100
+ "*"
101
+ elsif param[0] == :req
102
+ ":#{param[1]}"
103
+ elsif param[0] == :opt
104
+ ":#{param[1]}?"
105
+ end
106
+ o << pattern if pattern
107
+ }
108
+ end
109
+
5
110
  end
111
+
112
+ require 'sombrero/base_controller'
113
+ require 'sombrero/rtcp_controller'
data/sombrero.gemspec CHANGED
@@ -1,7 +1,10 @@
1
1
  # coding: utf-8
2
2
 
3
3
  Gem::Specification.new do |spec|
4
- spec.name, spec.version = %w[sombrero 0.0.1]
4
+ spec.name, spec.version = %w[
5
+ sombrero
6
+ 0.0.2
7
+ ]
5
8
  spec.authors = ['Slee Woo']
6
9
  spec.email = ['mail@sleewoo.com']
7
10
  spec.summary = [spec.name, spec.version]*'-',
@@ -16,4 +19,6 @@ Gem::Specification.new do |spec|
16
19
  spec.required_ruby_version = '~> 2.0'
17
20
 
18
21
  spec.add_runtime_dependency 'rocketio', '~> 0'
22
+ spec.add_development_dependency 'pry'
23
+ spec.add_development_dependency 'pry-byebug'
19
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sombrero
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Slee Woo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2016-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rocketio
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
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-byebug
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'
27
55
  description: Opinionated stack for building opinionated web applications
28
56
  email:
29
57
  - mail@sleewoo.com
@@ -37,9 +65,68 @@ files:
37
65
  - LICENSE.txt
38
66
  - README.md
39
67
  - Rakefile
68
+ - app/.gitignore
69
+ - app/.pryrc
70
+ - app/Gemfile
71
+ - app/Rakefile
72
+ - app/base/base_controller.rb
73
+ - app/base/boot.rb
74
+ - app/base/helpers/application_helpers.rb
75
+ - app/base/load_controllers.rb
76
+ - app/base/rtcp_controller.rb
77
+ - app/config.ru
78
+ - app/config/config.rb
79
+ - app/config/config.yml
80
+ - app/config/env/development.yml
81
+ - app/config/env/production.yml
82
+ - app/config/env/stage.yml
83
+ - app/config/env/test.yml
84
+ - app/core/Gemfile
85
+ - app/core/boot.rb
86
+ - app/core/client/activity_observer.coffee
87
+ - app/core/client/api.coffee
88
+ - app/core/client/channels.coffee
89
+ - app/core/client/load.coffee
90
+ - app/core/client/page.coffee
91
+ - app/core/client/polyfills.coffee
92
+ - app/core/client/polyfills/array.compact.coffee
93
+ - app/core/client/polyfills/array.compact_join.coffee
94
+ - app/core/client/polyfills/number.to_money.coffee
95
+ - app/core/client/polyfills/string.capitalize.coffee
96
+ - app/core/client/polyfills/string.strip.coffee
97
+ - app/core/client/render.coffee
98
+ - app/core/client/util.coffee
99
+ - app/core/client/util/alert.coffee
100
+ - app/core/client/util/datetime.coffee
101
+ - app/core/generate_controllers_map.rb
102
+ - app/core/generate_webpack_setup.rb
103
+ - app/core/load.rb
104
+ - app/core/load_controllers.rb
105
+ - app/package.json
106
+ - app/webpack.config.js
40
107
  - bin/sombrero
108
+ - docker/Dockerfile
109
+ - docker/base/Dockerfile
110
+ - docker/base/build
111
+ - docker/base/build.sh
112
+ - docker/cleanup
113
+ - docker/run
114
+ - docker/skel/build.sh
115
+ - docker/skel/config.yml
116
+ - docker/skel/prepare_build.sh
117
+ - docker/skel/start.sh
118
+ - docker/start
41
119
  - lib/sombrero.rb
42
- - lib/sombrero/version.rb
120
+ - lib/sombrero/app.rb
121
+ - lib/sombrero/base_controller.rb
122
+ - lib/sombrero/cli.rb
123
+ - lib/sombrero/cli/app.rb
124
+ - lib/sombrero/cli/app/install.rb
125
+ - lib/sombrero/cli/app/update.rb
126
+ - lib/sombrero/cli/docker.rb
127
+ - lib/sombrero/cli/docker/build.rb
128
+ - lib/sombrero/cli/docker/install.rb
129
+ - lib/sombrero/rtcp_controller.rb
43
130
  - sombrero.gemspec
44
131
  homepage: https://github.com/sleewoo/sombrero
45
132
  licenses:
@@ -64,5 +151,5 @@ rubyforge_project:
64
151
  rubygems_version: 2.5.1
65
152
  signing_key:
66
153
  specification_version: 4
67
- summary: '["sombrero-0.0.1", "Opinionated stack for building opinionated web applications"]'
154
+ summary: '["sombrero-0.0.2", "Opinionated stack for building opinionated web applications"]'
68
155
  test_files: []