ki 0.4.10 → 0.4.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +16 -8
  3. data/MIDDLEWARE.md +27 -7
  4. data/README.md +45 -2
  5. data/REALTIME.md +48 -0
  6. data/TODO.md +19 -0
  7. data/ki.gemspec +1 -0
  8. data/lib/ki.rb +5 -0
  9. data/lib/ki/base_request.rb +7 -0
  10. data/lib/ki/channel_manager.rb +58 -0
  11. data/lib/ki/ki.rb +1 -0
  12. data/lib/ki/ki_cli.rb +1 -1
  13. data/lib/ki/ki_config.rb +18 -2
  14. data/lib/ki/middleware/api_handler.rb +11 -16
  15. data/lib/ki/middleware/helpers/redirect_to_helper.rb +13 -0
  16. data/lib/ki/middleware/realtime.rb +81 -0
  17. data/lib/ki/model.rb +6 -4
  18. data/lib/ki/modules/restrictions.rb +4 -7
  19. data/lib/ki/orm.rb +38 -2
  20. data/lib/ki/utils/redirect_to_helper.rb +0 -0
  21. data/lib/ki/version.rb +1 -1
  22. data/spec/examples/json.northpole.ro/.bowerrc +3 -0
  23. data/spec/examples/json.northpole.ro/Gemfile +1 -0
  24. data/spec/examples/json.northpole.ro/bower.json +17 -0
  25. data/spec/examples/json.northpole.ro/config.ru +3 -0
  26. data/spec/examples/json.northpole.ro/config.yml +4 -0
  27. data/spec/examples/json.northpole.ro/config.yml.backup +18 -0
  28. data/spec/examples/json.northpole.ro/config/deploy.rb +2 -1
  29. data/spec/examples/json.northpole.ro/config/deploy/production.rb +4 -38
  30. data/spec/examples/json.northpole.ro/public/app/.bowerrc +3 -0
  31. data/spec/examples/json.northpole.ro/public/app/.gitignore +9 -0
  32. data/spec/examples/json.northpole.ro/public/app/.jshintrc +13 -0
  33. data/spec/examples/json.northpole.ro/public/app/.travis.yml +14 -0
  34. data/spec/examples/json.northpole.ro/public/app/LICENSE +22 -0
  35. data/spec/examples/json.northpole.ro/public/app/README.md +82 -0
  36. data/spec/examples/json.northpole.ro/public/app/bower.json +20 -0
  37. data/spec/examples/json.northpole.ro/public/app/e2e/pages/ContactUser.js +22 -0
  38. data/spec/examples/json.northpole.ro/public/app/e2e/pages/UserDetails.js +11 -0
  39. data/spec/examples/json.northpole.ro/public/app/e2e/pages/UserList.js +12 -0
  40. data/spec/examples/json.northpole.ro/public/app/e2e/protractor.conf.js +26 -0
  41. data/spec/examples/json.northpole.ro/public/app/e2e/scenarios/users.js +34 -0
  42. data/spec/examples/json.northpole.ro/public/app/gulpfile.js +104 -0
  43. data/spec/examples/json.northpole.ro/public/app/karma.conf.js +35 -0
  44. data/spec/examples/json.northpole.ro/public/app/package.json +30 -0
  45. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/avatar-1.svg +11 -0
  46. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/avatar-4.svg +16 -0
  47. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/avatars.svg +244 -0
  48. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/google_plus.svg +1 -0
  49. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/hangouts.svg +1 -0
  50. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/ic_fullscreen_48px.svg +4 -0
  51. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/ic_fullscreen_exit_48px.svg +4 -0
  52. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/ic_music_note_48px.svg +1 -0
  53. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/ic_note_add_48px.svg +1 -0
  54. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/ic_view_list_48px.svg +1 -0
  55. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/icon.svg +1 -0
  56. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/mail.svg +1 -0
  57. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/manggo.svg +1095 -0
  58. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/menu.svg +4 -0
  59. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/phone.svg +1 -0
  60. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/share.svg +3 -0
  61. data/spec/examples/json.northpole.ro/public/app/src/assets/svg/twitter.svg +1 -0
  62. data/spec/examples/json.northpole.ro/public/app/src/css/app.css +138 -0
  63. data/spec/examples/json.northpole.ro/public/app/src/css/app.css.map +7 -0
  64. data/spec/examples/json.northpole.ro/public/app/src/css/app.sass +145 -0
  65. data/spec/examples/json.northpole.ro/public/app/src/index.html +157 -0
  66. data/spec/examples/json.northpole.ro/public/app/src/js/MainController.coffee +167 -0
  67. data/spec/examples/json.northpole.ro/public/app/src/js/app.coffee +58 -0
  68. data/spec/examples/json.northpole.ro/public/app/src/js/blobs/BlobsController.coffee +115 -0
  69. data/spec/examples/json.northpole.ro/public/app/src/js/blobs/blobs.html +48 -0
  70. data/spec/examples/json.northpole.ro/public/app/src/js/tutorial/tutorial.html +15 -0
  71. data/spec/examples/json.northpole.ro/public/app/src/js/users/UserService.coffee +12 -0
  72. data/spec/examples/json.northpole.ro/public/app/src/js/users/Users.coffee +1 -0
  73. data/spec/examples/json.northpole.ro/public/app/src/js/users/users.html +8 -0
  74. data/spec/examples/json.northpole.ro/public/javascripts/jnorthpole.coffee +40 -7
  75. data/spec/examples/json.northpole.ro/public/javascripts/realtime.coffee +28 -0
  76. data/spec/examples/json.northpole.ro/public/{javascripts/music → music}/angular-youtube-embed.js +0 -0
  77. data/spec/examples/json.northpole.ro/public/music/index.html +126 -0
  78. data/spec/examples/json.northpole.ro/public/music/music.coffee +99 -0
  79. data/spec/examples/json.northpole.ro/public/music/music.sass +63 -0
  80. data/spec/examples/json.northpole.ro/public/stylesheets/app.sass +3 -0
  81. data/spec/examples/json.northpole.ro/views/faq.haml +7 -0
  82. data/spec/examples/json.northpole.ro/views/layout.haml +1 -0
  83. data/spec/examples/json.northpole.ro/views/music.haml +2 -0
  84. data/spec/examples/json.northpole.ro/views/websocket.haml +7 -0
  85. data/spec/lib/ki/channel_manager_spec.rb +82 -0
  86. data/spec/lib/ki/helpers_spec.rb +11 -0
  87. data/spec/lib/ki/ki_config_spec.rb +28 -0
  88. data/spec/lib/ki/middleware/admin_generator_spec.rb +8 -0
  89. data/spec/lib/ki/middleware/init_middleware_spec.rb +21 -0
  90. data/spec/lib/ki/middleware/realtime_spec.rb +96 -0
  91. data/spec/lib/ki/model_spec.rb +28 -7
  92. data/spec/lib/ki/modules/model_helper_spec.rb +31 -0
  93. data/spec/lib/ki/orm_spec.rb +26 -0
  94. metadata +211 -9
  95. data/spec/examples/json.northpole.ro/public/javascripts/docs.min.js +0 -16
  96. data/spec/examples/json.northpole.ro/views/awsum.haml +0 -108
@@ -9,6 +9,7 @@ module Ki
9
9
  # json output from the url, instead it will redirect to the url given
10
10
  class ApiHandler
11
11
  include BaseMiddleware
12
+ include Helpers::RedirectTo
12
13
 
13
14
  def call(env)
14
15
  req = BaseRequest.new env
@@ -26,26 +27,20 @@ module Ki
26
27
  fail InvalidUrlError.new("invalid url '#{req.path}'", 404)
27
28
  end
28
29
 
29
- model = klass.new(req.to_action, req.params)
30
- if req.params['redirect_to'].nil? # TODO: document this
31
- render model
32
- else
33
- redirect_to req.params['redirect_to'] # TODO: check for injection
34
- end
30
+ model = klass.new(req)
31
+ render model
35
32
  rescue ApiError => e
36
33
  render e
37
34
  end
38
35
 
39
- def redirect_to(s)
40
- resp = Rack::Response.new
41
- resp.redirect(s)
42
- resp.finish
43
- end
44
-
45
- def render(r)
46
- resp = Rack::Response.new(r.result.to_json, r.status)
47
- resp['Content-Type'] = 'application/json'
48
- resp.finish
36
+ def render(model)
37
+ if model.is_a?(ApiError) || model.params['redirect_to'].nil?
38
+ resp = Rack::Response.new(model.result.to_json, model.status)
39
+ resp['Content-Type'] = 'application/json'
40
+ resp.finish
41
+ else
42
+ redirect_to model.params['redirect_to']
43
+ end
49
44
  end
50
45
  end
51
46
  end
@@ -0,0 +1,13 @@
1
+ module Ki
2
+ module Middleware
3
+ module Helpers
4
+ module RedirectTo
5
+ def redirect_to(path)
6
+ resp = Rack::Response.new
7
+ resp.redirect(path)
8
+ resp.finish
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,81 @@
1
+ module Ki
2
+ module Middleware #:nodoc:
3
+ class Realtime
4
+ include BaseMiddleware
5
+
6
+ def call(env)
7
+ req = BaseRequest.new env
8
+ if req.path.to_s == '/realtime/info'
9
+ show_stats
10
+ elsif req.path.to_s == '/realtime' && Faye::WebSocket.websocket?(env)
11
+ handle_websocket env
12
+ else
13
+ @app.call env
14
+ end
15
+ end
16
+
17
+ def ws_send(ws, hash)
18
+ ws.send(hash.to_json.to_s)
19
+ end
20
+
21
+ def show_stats
22
+ hash = {
23
+ sockets: ::Ki::ChannelManager.sockets
24
+ }
25
+ resp = Rack::Response.new(hash.to_json, 200)
26
+ resp['Content-Type'] = 'application/json'
27
+ resp.finish
28
+ end
29
+
30
+ def handle_websocket(env)
31
+ ws = Faye::WebSocket.new(env)
32
+
33
+ socket = ::Ki::ChannelManager.connect
34
+ ws_send(ws, socket)
35
+
36
+ ws.on :message do |event|
37
+ on_message(ws, socket, event.data)
38
+ end
39
+
40
+ timer = EventMachine::PeriodicTimer.new(1) do
41
+ msgs = ::Ki::ChannelManager.tick(socket_id: socket['id'])
42
+ ws_send(ws, { messages: msgs }) if msgs.count > 0
43
+ end
44
+
45
+ ws.on :close do # |event|
46
+ timer.cancel
47
+ ::Ki::ChannelManager.disconnect socket
48
+ ws = nil
49
+ end
50
+
51
+ ws.rack_response
52
+ end
53
+
54
+ def on_message(ws, socket, data)
55
+ json = JSON.parse(data)
56
+ json['socket_id'] = socket['id']
57
+ if json['type'] == 'subscribe'
58
+ channel_manager_action(json, ws, 'subscribe')
59
+ elsif json['type'] == 'unsubscribe'
60
+ output = ::Ki::ChannelManager.unsubscribe json
61
+ ws_send(ws, output)
62
+ elsif json['type'] == 'publish'
63
+ channel_manager_action(json, ws, 'publish')
64
+ else
65
+ ws_send(ws, { message: 'Please specify a valid type' })
66
+ end
67
+ rescue JSON::ParserError
68
+ ws_send(ws, { message: 'Please send a valid json string' })
69
+ end
70
+
71
+ def channel_manager_action(json, ws, action)
72
+ if json['channel_name']
73
+ output = ::Ki::ChannelManager.send(action, json)
74
+ ws_send(ws, output)
75
+ else
76
+ ws_send(ws, { message: 'Please specify a channel_name' })
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
data/lib/ki/model.rb CHANGED
@@ -4,12 +4,14 @@ module Ki
4
4
  extend Restrictions
5
5
  include Callbacks
6
6
  include ModelHelper
7
+ include Middleware::Helpers::RedirectTo
7
8
 
8
- attr_accessor :action, :result, :params, :status
9
+ attr_accessor :action, :result, :params, :status, :req
9
10
 
10
- def initialize(action, params)
11
- @action = action
12
- @params = params
11
+ def initialize(req)
12
+ @req = req
13
+ @action = req.to_action
14
+ @params = req.params
13
15
  @status = 200
14
16
 
15
17
  fail ForbiddenAction if forbidden_actions.include? @action
@@ -28,13 +28,10 @@ module Ki
28
28
  private
29
29
 
30
30
  def generic_restriction(method_name, attributes)
31
- send :define_method, method_name do
32
- attributes
33
- end
34
-
35
- eigen_class = class << self; self; end
36
- eigen_class.send(:define_method, method_name) do
37
- attributes
31
+ [:define_method, :define_singleton_method].each do |definition_means|
32
+ send definition_means, method_name do
33
+ attributes
34
+ end
38
35
  end
39
36
  end
40
37
  end
data/lib/ki/orm.rb CHANGED
@@ -103,7 +103,14 @@ module Ki
103
103
  #
104
104
  def find(name, hash = {})
105
105
  hash = nourish_hash_id hash
106
- @db[name].find(hash).to_a.stringify_ids
106
+ a = nourish_hash_limit hash
107
+ hash = a[0]
108
+ limit = a[1]
109
+ a = nourish_hash_sort hash
110
+ hash = a[0]
111
+ sort = a[1]
112
+
113
+ @db[name].find(hash, limit).sort(sort).to_a.stringify_ids
107
114
  end
108
115
 
109
116
  # Update a hash from the database
@@ -156,7 +163,7 @@ module Ki
156
163
  hash = nourish_hash_id hash
157
164
  r = @db[name].remove hash
158
165
  {
159
- deleted_item_count: r["n"] || 0
166
+ deleted_item_count: r['n'] || 0
160
167
  }
161
168
  end
162
169
 
@@ -198,6 +205,35 @@ module Ki
198
205
  end
199
206
  hash
200
207
  end
208
+
209
+ def nourish_hash_limit(hash)
210
+ tmp = {}
211
+ if hash['__limit']
212
+ # really need to work on hash_with_indifferent access
213
+ # if you change how you access the symbol you will have a bad time
214
+ tmp[:limit] = hash['__limit']
215
+ hash.delete('__limit')
216
+ end
217
+ [hash, tmp]
218
+ end
219
+
220
+ def nourish_hash_sort(hash)
221
+ tmp = {}
222
+ if hash['__sort']
223
+ if hash['__sort'].class != Hash
224
+ tmp = {}
225
+ else
226
+ # TODO: validate for size and number of elements
227
+ # TODO: validate value
228
+ # TODO: handle sorting by id
229
+ hash['__sort'].to_a.each do |e|
230
+ tmp[e[0].to_sym] = e[1].to_sym
231
+ end
232
+ end
233
+ hash.delete('__sort')
234
+ end
235
+ [hash, tmp]
236
+ end
201
237
  end
202
238
  end
203
239
  end
File without changes
data/lib/ki/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ki
2
- VERSION = '0.4.10'
2
+ VERSION = '0.4.11'
3
3
  end
@@ -0,0 +1,3 @@
1
+ {
2
+ "directory": "public/components/"
3
+ }
@@ -2,5 +2,6 @@ source "https://rubygems.org"
2
2
 
3
3
  gem 'ki', :path => '../../..'
4
4
  gem 'passenger', '4.0.40'
5
+ gem 'thin'
5
6
  gem 'capistrano'
6
7
  gem 'capistrano-rvm'
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "json.northpole.ro",
3
+ "version": "0.4.10",
4
+ "homepage": "https://github.com/mess110/ki",
5
+ "authors": [
6
+ "Cristian Mircea Messel <mess110@gmail.com>"
7
+ ],
8
+ "license": "MIT",
9
+ "ignore": [
10
+ "**/.*",
11
+ "node_modules",
12
+ "bower_components",
13
+ "public/components/",
14
+ "test",
15
+ "tests"
16
+ ]
17
+ }
@@ -1,3 +1,6 @@
1
1
  require './app'
2
+ unless `hostname`.include?('glassic-jenkins')
3
+ Faye::WebSocket.load_adapter('thin')
4
+ end
2
5
  use Rack::Reloader, 0
3
6
  run Ki::Ki.new
@@ -2,7 +2,9 @@ development:
2
2
  database:
3
3
  name: np_development
4
4
  host: 127.0.0.1
5
+ # host: 172.17.0.3
5
6
  port: 27017
7
+ add_middleware: 'Realtime'
6
8
 
7
9
  test:
8
10
  database:
@@ -14,4 +16,6 @@ production:
14
16
  database:
15
17
  name: np
16
18
  host: 127.0.0.1
19
+ # host: 172.17.0.3
17
20
  port: 27017
21
+ add_middleware: 'Realtime'
@@ -0,0 +1,18 @@
1
+ development:
2
+ database:
3
+ name: np_development
4
+ host: 172.17.0.3
5
+ port: 27017
6
+
7
+ test:
8
+ database:
9
+ name: np_test
10
+ host: 127.0.0.1
11
+ port: 27017
12
+
13
+ production:
14
+ database:
15
+ name: np
16
+ host: 127.0.0.1
17
+ port: 27017
18
+ add_middleware: 'Realtime'
@@ -30,7 +30,7 @@ set :deploy_to, '/home/kiki/json.northpole.ro'
30
30
 
31
31
  # Default value for default_env is {}
32
32
  # set :default_env, { path: "/opt/ruby/bin:$PATH" }
33
- set :rvm_ruby_version, '2.1.0@coinmarketcap'
33
+ set :rvm_ruby_version, '2.1.2@json.northpole.ro'
34
34
 
35
35
  # Default value for keep_releases is 5
36
36
  # set :keep_releases, 5
@@ -42,6 +42,7 @@ namespace :deploy do
42
42
  on roles(:app), in: :sequence, wait: 5 do
43
43
  # Your restart mechanism here, for example:
44
44
  # execute :touch, release_path.join('tmp/restart.txt')
45
+ # run "#{sudo} service nginx #{command}"
45
46
  end
46
47
  end
47
48
 
@@ -1,39 +1,5 @@
1
- # Simple Role Syntax
2
- # ==================
3
- # Supports bulk-adding hosts to roles, the primary
4
- # server in each group is considered to be the first
5
- # unless any hosts have the primary property set.
6
- # Don't declare `role :all`, it's a meta role
7
- role :app, %w{kiki@northpole.ro}
8
- role :web, %w{kiki@northpole.ro}
9
- role :db, %w{kiki@northpole.ro}
1
+ role :app, %w{mace@glassic.northpole.ro}
2
+ role :web, %w{mace@glassic.northpole.ro}
3
+ role :db, %w{mace@glassic.northpole.ro}
10
4
 
11
- # Extended Server Syntax
12
- # ======================
13
- # This can be used to drop a more detailed server
14
- # definition into the server list. The second argument
15
- # something that quacks like a hash can be used to set
16
- # extended properties on the server.
17
- # server 'example.com', user: 'deploy', roles: %w{web app}, my_property: :my_value
18
-
19
- # you can set custom ssh options
20
- # it's possible to pass any option but you need to keep in mind that net/ssh understand limited list of options
21
- # you can see them in [net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start)
22
- # set it globally
23
- # set :ssh_options, {
24
- # keys: %w(/home/rlisowski/.ssh/id_rsa),
25
- # forward_agent: false,
26
- # auth_methods: %w(password)
27
- # }
28
- # and/or per server
29
- # server 'example.com',
30
- # user: 'user_name',
31
- # roles: %w{web app},
32
- # ssh_options: {
33
- # user: 'user_name', # overrides user setting above
34
- # keys: %w(/home/user_name/.ssh/id_rsa),
35
- # forward_agent: false,
36
- # auth_methods: %w(publickey password)
37
- # # password: 'please use keys'
38
- # }
39
- # setting per server overrides global ssh_options
5
+ set :deploy_to, '/home/mace/json.northpole.ro'
@@ -0,0 +1,3 @@
1
+ {
2
+ "directory": "bower_components"
3
+ }
@@ -0,0 +1,9 @@
1
+ logs/*
2
+ !.gitkeep
3
+ node_modules/
4
+ bower_components/
5
+ tmp
6
+ .DS_Store
7
+ .idea
8
+ app/jspm_packages
9
+ build/
@@ -0,0 +1,13 @@
1
+ {
2
+ "globalstrict": true,
3
+ "globals": {
4
+ "angular": false,
5
+ "describe": false,
6
+ "it": false,
7
+ "expect": false,
8
+ "beforeEach": false,
9
+ "afterEach": false,
10
+ "module": false,
11
+ "inject": false
12
+ }
13
+ }
@@ -0,0 +1,14 @@
1
+ language: node_js
2
+ node_js:
3
+ - "0.10"
4
+
5
+ before_script:
6
+ - export DISPLAY=:99.0
7
+ - sh -e /etc/init.d/xvfb start
8
+ - npm start > /dev/null &
9
+ - npm run update-webdriver
10
+ - sleep 1 # give server time to start
11
+
12
+ script:
13
+ - node_modules/.bin/karma start karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox
14
+ - node_modules/.bin/protractor e2e-tests/protractor.conf.js --browser=firefox
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+