ki 0.4.11 → 0.4.12

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +9 -0
  4. data/.ruby-gemset +1 -1
  5. data/.ruby-version +1 -1
  6. data/.travis.yml +10 -2
  7. data/Gemfile +2 -0
  8. data/Gemfile.lock +95 -85
  9. data/Guardfile +20 -14
  10. data/MIDDLEWARE.md +2 -2
  11. data/README.md +29 -1
  12. data/Rakefile +3 -1
  13. data/bin/ki +1 -0
  14. data/ki.gemspec +15 -14
  15. data/lib/ki.rb +8 -1
  16. data/lib/ki/base_request.rb +7 -5
  17. data/lib/ki/channel_manager.rb +2 -0
  18. data/lib/ki/helpers.rb +4 -5
  19. data/lib/ki/ki.rb +11 -2
  20. data/lib/ki/ki_app.rb +2 -0
  21. data/lib/ki/ki_cli.rb +9 -2
  22. data/lib/ki/ki_config.rb +5 -2
  23. data/lib/ki/ki_logger.rb +15 -0
  24. data/lib/ki/middleware/admin_interface_generator.rb +3 -1
  25. data/lib/ki/middleware/api_handler.rb +3 -1
  26. data/lib/ki/middleware/base_middleware.rb +2 -0
  27. data/lib/ki/middleware/coffee_compiler.rb +2 -0
  28. data/lib/ki/middleware/haml_compiler.rb +2 -0
  29. data/lib/ki/middleware/helpers/format_of_helper.rb +3 -1
  30. data/lib/ki/middleware/helpers/haml_compiler_helper.rb +7 -5
  31. data/lib/ki/middleware/helpers/public_file_helper.rb +2 -0
  32. data/lib/ki/middleware/helpers/redirect_to_helper.rb +2 -0
  33. data/lib/ki/middleware/helpers/view_helper.rb +2 -0
  34. data/lib/ki/middleware/init_middleware.rb +2 -0
  35. data/lib/ki/middleware/{doc_generator.rb → insta_doc.rb} +8 -6
  36. data/lib/ki/middleware/public_file_server.rb +2 -0
  37. data/lib/ki/middleware/realtime.rb +3 -1
  38. data/lib/ki/middleware/sass_compiler.rb +2 -0
  39. data/lib/ki/model.rb +8 -7
  40. data/lib/ki/modules/callbacks.rb +12 -20
  41. data/lib/ki/modules/model_helper.rb +2 -0
  42. data/lib/ki/modules/query_interface.rb +2 -0
  43. data/lib/ki/modules/restrictions.rb +5 -2
  44. data/lib/ki/orm.rb +20 -13
  45. data/lib/ki/utils/annotations.rb +33 -0
  46. data/lib/ki/utils/api_error.rb +14 -4
  47. data/lib/ki/utils/descendants.rb +9 -0
  48. data/lib/ki/utils/extra_irb.rb +3 -1
  49. data/lib/ki/utils/extra_ruby.rb +12 -0
  50. data/lib/ki/utils/indifferent_hash.rb +2 -0
  51. data/lib/ki/utils/logger.rb +5 -0
  52. data/lib/ki/version.rb +3 -1
  53. data/lib/ki/views/instadoc.haml +49 -9
  54. data/spec/config.yml.example +1 -1
  55. data/spec/examples/base/client.rb +20 -0
  56. data/spec/examples/base/logs/.keep +0 -0
  57. data/spec/examples/base/public/javascripts/app.js +12 -0
  58. data/spec/examples/json.northpole.ro/.ruby-version +1 -1
  59. data/spec/examples/json.northpole.ro/public/javascripts/app.coffee +1 -0
  60. data/spec/functional_spec.rb +2 -0
  61. data/spec/lib/ki/base_request_spec.rb +25 -23
  62. data/spec/lib/ki/channel_manager_spec.rb +2 -0
  63. data/spec/lib/ki/helpers_spec.rb +4 -2
  64. data/spec/lib/ki/indifferent_hash_spec.rb +2 -0
  65. data/spec/lib/ki/ki_app_spec.rb +2 -0
  66. data/spec/lib/ki/ki_config_spec.rb +5 -3
  67. data/spec/lib/ki/ki_spec.rb +2 -0
  68. data/spec/lib/ki/middleware/admin_generator_spec.rb +2 -0
  69. data/spec/lib/ki/middleware/haml_compiler_spec.rb +6 -3
  70. data/spec/lib/ki/middleware/helpers/format_of_helper_spec.rb +4 -2
  71. data/spec/lib/ki/middleware/init_middleware_spec.rb +3 -1
  72. data/spec/lib/ki/middleware/{doc_generator_spec.rb → insta_doc_spec.rb} +3 -1
  73. data/spec/lib/ki/middleware/realtime_spec.rb +12 -6
  74. data/spec/lib/ki/middleware_spec.rb +3 -1
  75. data/spec/lib/ki/model_spec.rb +26 -22
  76. data/spec/lib/ki/modules/model_helper_spec.rb +5 -3
  77. data/spec/lib/ki/modules/restrictions_spec.rb +16 -0
  78. data/spec/lib/ki/orm_spec.rb +18 -15
  79. data/spec/lib/ki/utils/api_error_spec.rb +9 -0
  80. data/spec/spec_helper.rb +13 -7
  81. data/spec/util_spec.rb +3 -1
  82. metadata +44 -30
data/lib/ki.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # ruby stdlib
2
4
  require 'yaml'
3
5
  require 'uri'
@@ -12,10 +14,14 @@ require 'coffee-script'
12
14
  require 'mongo'
13
15
  require 'faye/websocket'
14
16
  require 'eventmachine'
17
+ require 'logger'
15
18
 
16
19
  # code
20
+ require 'ki/utils/annotations'
21
+ require 'ki/utils/descendants'
17
22
  require 'ki/utils/api_error'
18
23
  require 'ki/utils/extra_ruby'
24
+ require 'ki/utils/logger'
19
25
  require 'ki/utils/indifferent_hash'
20
26
 
21
27
  require 'ki/modules/query_interface'
@@ -36,11 +42,12 @@ require 'ki/middleware/public_file_server'
36
42
  require 'ki/middleware/sass_compiler'
37
43
  require 'ki/middleware/haml_compiler'
38
44
  require 'ki/middleware/coffee_compiler'
39
- require 'ki/middleware/doc_generator'
45
+ require 'ki/middleware/insta_doc'
40
46
  require 'ki/middleware/admin_interface_generator'
41
47
  require 'ki/middleware/realtime'
42
48
 
43
49
  require 'ki/ki_config'
50
+ require 'ki/ki_logger'
44
51
  require 'ki/helpers'
45
52
  require 'ki/orm'
46
53
  require 'ki/model'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  class BaseRequest < Rack::Request
3
5
  include Middleware::Helpers::FormatOf
@@ -20,13 +22,13 @@ module Ki
20
22
 
21
23
  def headers
22
24
  Hash[*env.select { |k, _v| k.start_with? 'HTTP_' }
23
- .collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
24
- .sort
25
- .flatten]
25
+ .collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
26
+ .sort
27
+ .flatten]
26
28
  end
27
29
 
28
30
  def to_ki_model_class
29
- path.to_s.gsub('/', '').gsub(format_of(path), '').gsub('.', '').to_class
31
+ path.to_s.delete('/').gsub(format_of(path), '').delete('.').to_class
30
32
  end
31
33
 
32
34
  def to_action
@@ -42,7 +44,7 @@ module Ki
42
44
  when 'SEARCH'
43
45
  :find
44
46
  else
45
- fail 'unkown action'
47
+ raise 'unkown action'
46
48
  end
47
49
  end
48
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  class ChannelManager
3
5
  def self.connect
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Helpers
3
5
  include Middleware::Helpers::View
@@ -16,11 +18,8 @@ module Ki
16
18
 
17
19
  def partial(s)
18
20
  path = view_path(s)
19
- if File.file?(path)
20
- haml(File.read(path))
21
- else
22
- fail PartialNotFoundError, path
23
- end
21
+ raise PartialNotFoundError, path unless File.file?(path)
22
+ haml(File.read(path))
24
23
  end
25
24
  end
26
25
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  class Ki
3
5
  PUBLIC_PATH = 'public'
@@ -8,6 +10,14 @@ module Ki
8
10
 
9
11
  @app = Rack::Builder.new do
10
12
  use Middleware::InitMiddleware
13
+
14
+ if Dir.exist?('logs')
15
+ logfile = ::File.join('logs', 'requests.log')
16
+ logger = ::Logger.new(logfile, 'weekly')
17
+ KiLogger.instance.init(logger)
18
+ use Rack::CommonLogger, logger
19
+ end
20
+
11
21
  use Rack::Parser, content_types: {
12
22
  'application/json' => proc { |body| ::MultiJson.decode body }
13
23
  }
@@ -15,8 +25,7 @@ module Ki
15
25
  use Rack::Cors do
16
26
  allow do
17
27
  origins '*'
18
- resource '*', headers: :any, methods: [:get, :search, :put, :post, :delete]
19
- # resource '*', headers: :any, methods: :any # TODO: find out why :any doesn't work
28
+ resource '*', headers: :any, methods: %i[get search put post delete]
20
29
  end
21
30
  end
22
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  class KiApp
3
5
  include Middleware::Helpers::HamlCompiler
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
2
4
 
3
5
  require 'ki/utils/extra_irb'
@@ -7,15 +9,20 @@ module Ki
7
9
  class KiGenerator < Thor::Group #:nodoc:
8
10
  include Thor::Actions
9
11
 
12
+ def self.say(s)
13
+ puts s
14
+ end
15
+
10
16
  def self.source_root
11
17
  File.join(File.dirname(__FILE__), '..', '..')
12
18
  end
13
19
 
14
20
  def self.requires_ki_directory
15
- unless File.exist? 'config.ru'
21
+ unless File.exist?('config.ru')
16
22
  say 'Working directory should be a ki app.'
17
23
  exit 3
18
24
  end
25
+ say 'Found config.ru'
19
26
  end
20
27
  end
21
28
 
@@ -23,7 +30,7 @@ module Ki
23
30
  argument :app_name
24
31
 
25
32
  def prepare_dir
26
- unless app_name =~ /^[a-zA-Z0-9-]*$/
33
+ unless app_name.match?(/^[a-zA-Z0-9-]*$/)
27
34
  say 'App name must contain only alphanumeric characters and -'
28
35
  exit 1
29
36
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'singleton'
2
4
 
3
5
  module Ki
@@ -5,6 +7,7 @@ module Ki
5
7
  include Singleton
6
8
 
7
9
  attr_reader :config, :environment
10
+ attr_accessor :logger
8
11
 
9
12
  def read(environment)
10
13
  @environment = environment
@@ -21,8 +24,8 @@ module Ki
21
24
  end
22
25
 
23
26
  def middleware
24
- used_middleware = %w(ApiHandler CoffeeCompiler SassCompiler HamlCompiler
25
- PublicFileServer)
27
+ used_middleware = %w[ApiHandler CoffeeCompiler SassCompiler HamlCompiler
28
+ PublicFileServer]
26
29
  used_middleware = @config['middleware'] if @config['middleware']
27
30
 
28
31
  used_middleware = add_rm_middleware used_middleware, 'add_middleware', 'push'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ module Ki
6
+ class KiLogger
7
+ include Singleton
8
+
9
+ attr_accessor :logger
10
+
11
+ def init logger
12
+ @logger = logger
13
+ end
14
+ end
15
+ end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
- class AdminInterfaceGenerator < DocGenerator
5
+ class AdminInterfaceGenerator < InstaDoc
4
6
  def custom_view_path
5
7
  File.join(File.dirname(__FILE__), '..', 'views', 'instadmin.haml')
6
8
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware #:nodoc:
3
5
  # Handles all API calls
@@ -24,7 +26,7 @@ module Ki
24
26
  klass = req.to_ki_model_class
25
27
 
26
28
  unless Model.descendants.include?(klass)
27
- fail InvalidUrlError.new("invalid url '#{req.path}'", 404)
29
+ raise InvalidUrlError.new("invalid url '#{req.path}'", 404)
28
30
  end
29
31
 
30
32
  model = klass.new(req)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware #:nodoc:
3
5
  module BaseMiddleware
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware #:nodoc:
3
5
  class CoffeeCompiler
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  class HamlCompiler
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  module Helpers
4
6
  module FormatOf
5
7
  def format_of(uri)
6
8
  uri = uri.path if uri.class == BaseRequest
7
- File.extname(URI.parse(uri).path).gsub('.', '')
9
+ File.extname(URI.parse(uri).path).delete('.')
8
10
  rescue URI::InvalidURIError
9
11
  ''
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  module Helpers
@@ -5,11 +7,11 @@ module Ki
5
7
  def render_haml_file(file_path, layout = true)
6
8
  file_contents = File.read(file_path)
7
9
 
8
- if layout && view_exists?('layout')
9
- layout_contents = File.read(view_path('layout'))
10
- else
11
- layout_contents = '= yield'
12
- end
10
+ layout_contents = if layout && view_exists?('layout')
11
+ File.read(view_path('layout'))
12
+ else
13
+ '= yield'
14
+ end
13
15
 
14
16
  html = render_haml(layout_contents).render do
15
17
  render_haml(file_contents).render
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  module Helpers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  module Helpers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  module Helpers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
5
  class InitMiddleware
@@ -1,16 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware
3
- class DocGenerator < HamlCompiler
5
+ class InstaDoc < HamlCompiler
4
6
  include BaseMiddleware
5
7
 
6
8
  def call(env)
7
9
  req = BaseRequest.new env
8
10
  if custom_check(req)
9
- if view_exists?(req)
10
- html = render_haml_file view_path(req)
11
- else
12
- html = render_haml_file custom_view_path
13
- end
11
+ html = if view_exists?(req)
12
+ render_haml_file view_path(req)
13
+ else
14
+ render_haml_file custom_view_path
15
+ end
14
16
  Rack::Response.new(html).finish
15
17
  else
16
18
  @app.call env
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware #:nodoc:
3
5
  class PublicFileServer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware #:nodoc:
3
5
  class Realtime
@@ -39,7 +41,7 @@ module Ki
39
41
 
40
42
  timer = EventMachine::PeriodicTimer.new(1) do
41
43
  msgs = ::Ki::ChannelManager.tick(socket_id: socket['id'])
42
- ws_send(ws, { messages: msgs }) if msgs.count > 0
44
+ ws_send(ws, { messages: msgs }) if msgs.count.positive?
43
45
  end
44
46
 
45
47
  ws.on :close do # |event|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  module Middleware #:nodoc:
3
5
  class SassCompiler
@@ -1,11 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  class Model
5
+ extend Descendants
3
6
  extend QueryInterface
4
7
  extend Restrictions
5
8
  include Callbacks
6
9
  include ModelHelper
7
10
  include Middleware::Helpers::RedirectTo
8
11
 
12
+ annotate!
13
+
9
14
  attr_accessor :action, :result, :params, :status, :req
10
15
 
11
16
  def initialize(req)
@@ -14,7 +19,7 @@ module Ki
14
19
  @params = req.params
15
20
  @status = 200
16
21
 
17
- fail ForbiddenAction if forbidden_actions.include? @action
22
+ raise ForbiddenAction if forbidden_actions.include? @action
18
23
 
19
24
  ccall
20
25
  end
@@ -44,7 +49,7 @@ module Ki
44
49
  def check_for_required_attributes
45
50
  required_attributes.each do |ra|
46
51
  unless @params.keys.include?(ra.to_s)
47
- fail RequiredAttributeMissing, "#{ra} missing"
52
+ raise RequiredAttributeMissing, "#{ra} missing"
48
53
  end
49
54
  end
50
55
  end
@@ -52,7 +57,7 @@ module Ki
52
57
  def check_for_unique_attributes
53
58
  unique_attributes.each do |ua|
54
59
  u = self.class.find({ ua.to_s => @params[ua.to_s] })
55
- fail AttributeNotUnique, "#{ua} not unique" unless u.empty?
60
+ raise AttributeNotUnique, "#{ua} not unique" unless u.empty?
56
61
  end
57
62
  end
58
63
 
@@ -63,9 +68,5 @@ module Ki
63
68
  send "after_#{@action}".to_sym
64
69
  after_all
65
70
  end
66
-
67
- def self.descendants
68
- ObjectSpace.each_object(Class).select { |klass| klass < self }
69
- end
70
71
  end
71
72
  end
@@ -1,35 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ki
2
4
  class Model
3
5
  module Callbacks
4
- def before_all
5
- end
6
+ def before_all; end
6
7
 
7
- def before_find
8
- end
8
+ def before_find; end
9
9
 
10
- def after_find
11
- end
10
+ def after_find; end
12
11
 
13
- def before_create
14
- end
12
+ def before_create; end
15
13
 
16
- def after_create
17
- end
14
+ def after_create; end
18
15
 
19
- def before_update
20
- end
16
+ def before_update; end
21
17
 
22
- def after_update
23
- end
18
+ def after_update; end
24
19
 
25
- def before_delete
26
- end
20
+ def before_delete; end
27
21
 
28
- def after_delete
29
- end
22
+ def after_delete; end
30
23
 
31
- def after_all
32
- end
24
+ def after_all; end
33
25
  end
34
26
  end
35
27
  end