ki 0.4.11 → 0.4.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +9 -0
- data/.ruby-gemset +1 -1
- data/.ruby-version +1 -1
- data/.travis.yml +10 -2
- data/Gemfile +2 -0
- data/Gemfile.lock +95 -85
- data/Guardfile +20 -14
- data/MIDDLEWARE.md +2 -2
- data/README.md +29 -1
- data/Rakefile +3 -1
- data/bin/ki +1 -0
- data/ki.gemspec +15 -14
- data/lib/ki.rb +8 -1
- data/lib/ki/base_request.rb +7 -5
- data/lib/ki/channel_manager.rb +2 -0
- data/lib/ki/helpers.rb +4 -5
- data/lib/ki/ki.rb +11 -2
- data/lib/ki/ki_app.rb +2 -0
- data/lib/ki/ki_cli.rb +9 -2
- data/lib/ki/ki_config.rb +5 -2
- data/lib/ki/ki_logger.rb +15 -0
- data/lib/ki/middleware/admin_interface_generator.rb +3 -1
- data/lib/ki/middleware/api_handler.rb +3 -1
- data/lib/ki/middleware/base_middleware.rb +2 -0
- data/lib/ki/middleware/coffee_compiler.rb +2 -0
- data/lib/ki/middleware/haml_compiler.rb +2 -0
- data/lib/ki/middleware/helpers/format_of_helper.rb +3 -1
- data/lib/ki/middleware/helpers/haml_compiler_helper.rb +7 -5
- data/lib/ki/middleware/helpers/public_file_helper.rb +2 -0
- data/lib/ki/middleware/helpers/redirect_to_helper.rb +2 -0
- data/lib/ki/middleware/helpers/view_helper.rb +2 -0
- data/lib/ki/middleware/init_middleware.rb +2 -0
- data/lib/ki/middleware/{doc_generator.rb → insta_doc.rb} +8 -6
- data/lib/ki/middleware/public_file_server.rb +2 -0
- data/lib/ki/middleware/realtime.rb +3 -1
- data/lib/ki/middleware/sass_compiler.rb +2 -0
- data/lib/ki/model.rb +8 -7
- data/lib/ki/modules/callbacks.rb +12 -20
- data/lib/ki/modules/model_helper.rb +2 -0
- data/lib/ki/modules/query_interface.rb +2 -0
- data/lib/ki/modules/restrictions.rb +5 -2
- data/lib/ki/orm.rb +20 -13
- data/lib/ki/utils/annotations.rb +33 -0
- data/lib/ki/utils/api_error.rb +14 -4
- data/lib/ki/utils/descendants.rb +9 -0
- data/lib/ki/utils/extra_irb.rb +3 -1
- data/lib/ki/utils/extra_ruby.rb +12 -0
- data/lib/ki/utils/indifferent_hash.rb +2 -0
- data/lib/ki/utils/logger.rb +5 -0
- data/lib/ki/version.rb +3 -1
- data/lib/ki/views/instadoc.haml +49 -9
- data/spec/config.yml.example +1 -1
- data/spec/examples/base/client.rb +20 -0
- data/spec/examples/base/logs/.keep +0 -0
- data/spec/examples/base/public/javascripts/app.js +12 -0
- data/spec/examples/json.northpole.ro/.ruby-version +1 -1
- data/spec/examples/json.northpole.ro/public/javascripts/app.coffee +1 -0
- data/spec/functional_spec.rb +2 -0
- data/spec/lib/ki/base_request_spec.rb +25 -23
- data/spec/lib/ki/channel_manager_spec.rb +2 -0
- data/spec/lib/ki/helpers_spec.rb +4 -2
- data/spec/lib/ki/indifferent_hash_spec.rb +2 -0
- data/spec/lib/ki/ki_app_spec.rb +2 -0
- data/spec/lib/ki/ki_config_spec.rb +5 -3
- data/spec/lib/ki/ki_spec.rb +2 -0
- data/spec/lib/ki/middleware/admin_generator_spec.rb +2 -0
- data/spec/lib/ki/middleware/haml_compiler_spec.rb +6 -3
- data/spec/lib/ki/middleware/helpers/format_of_helper_spec.rb +4 -2
- data/spec/lib/ki/middleware/init_middleware_spec.rb +3 -1
- data/spec/lib/ki/middleware/{doc_generator_spec.rb → insta_doc_spec.rb} +3 -1
- data/spec/lib/ki/middleware/realtime_spec.rb +12 -6
- data/spec/lib/ki/middleware_spec.rb +3 -1
- data/spec/lib/ki/model_spec.rb +26 -22
- data/spec/lib/ki/modules/model_helper_spec.rb +5 -3
- data/spec/lib/ki/modules/restrictions_spec.rb +16 -0
- data/spec/lib/ki/orm_spec.rb +18 -15
- data/spec/lib/ki/utils/api_error_spec.rb +9 -0
- data/spec/spec_helper.rb +13 -7
- data/spec/util_spec.rb +3 -1
- 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/
|
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'
|
data/lib/ki/base_request.rb
CHANGED
@@ -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
|
-
|
24
|
-
|
25
|
-
|
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.
|
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
|
-
|
47
|
+
raise 'unkown action'
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
data/lib/ki/channel_manager.rb
CHANGED
data/lib/ki/helpers.rb
CHANGED
@@ -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
|
-
|
20
|
-
|
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
|
data/lib/ki/ki.rb
CHANGED
@@ -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: [
|
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
|
data/lib/ki/ki_app.rb
CHANGED
data/lib/ki/ki_cli.rb
CHANGED
@@ -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?
|
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
|
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
|
data/lib/ki/ki_config.rb
CHANGED
@@ -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
|
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'
|
data/lib/ki/ki_logger.rb
ADDED
@@ -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
|
-
|
29
|
+
raise InvalidUrlError.new("invalid url '#{req.path}'", 404)
|
28
30
|
end
|
29
31
|
|
30
32
|
model = klass.new(req)
|
@@ -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).
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Ki
|
2
4
|
module Middleware
|
3
|
-
class
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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 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
|
44
|
+
ws_send(ws, { messages: msgs }) if msgs.count.positive?
|
43
45
|
end
|
44
46
|
|
45
47
|
ws.on :close do # |event|
|
data/lib/ki/model.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/ki/modules/callbacks.rb
CHANGED
@@ -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
|