ki 0.4.6 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +24 -0
- data/Gemfile.lock +25 -6
- data/Guardfile +11 -5
- data/README.md +78 -0
- data/Rakefile +4 -4
- data/ki.gemspec +24 -23
- data/lib/ki.rb +7 -4
- data/lib/ki/base_request.rb +2 -2
- data/lib/ki/helpers.rb +7 -7
- data/lib/ki/ki.rb +12 -18
- data/lib/ki/ki_app.rb +16 -0
- data/lib/ki/ki_cli.rb +11 -12
- data/lib/ki/ki_config.rb +12 -8
- data/lib/ki/middleware/admin_interface_generator.rb +1 -1
- data/lib/ki/middleware/api_handler.rb +7 -8
- data/lib/ki/middleware/base_middleware.rb +1 -1
- data/lib/ki/middleware/coffee_compiler.rb +2 -2
- data/lib/ki/middleware/doc_generator.rb +5 -4
- data/lib/ki/middleware/haml_compiler.rb +4 -22
- data/lib/ki/{modules/format_of.rb → middleware/helpers/format_of_helper.rb} +3 -3
- data/lib/ki/middleware/helpers/haml_compiler_helper.rb +27 -0
- data/lib/ki/{modules → middleware/helpers}/public_file_helper.rb +2 -2
- data/lib/ki/{modules → middleware/helpers}/view_helper.rb +3 -3
- data/lib/ki/middleware/init_middleware.rb +1 -1
- data/lib/ki/middleware/public_file_server.rb +1 -1
- data/lib/ki/middleware/sass_compiler.rb +3 -3
- data/lib/ki/model.rb +10 -11
- data/lib/ki/modules/{model_helpers.rb → model_helper.rb} +1 -1
- data/lib/ki/modules/query_interface.rb +7 -7
- data/lib/ki/modules/restrictions.rb +4 -5
- data/lib/ki/orm.rb +11 -11
- data/lib/ki/utils/api_error.rb +4 -4
- data/lib/ki/utils/extra_ruby.rb +3 -3
- data/lib/ki/utils/indifferent_hash.rb +1 -1
- data/lib/ki/version.rb +1 -1
- data/lib/ki/views/404.haml +1 -0
- data/lib/ki/views/instadmin.haml +47 -4
- data/spec/examples/base/app.rb +5 -0
- data/spec/examples/json.northpole.ro/Gemfile +1 -1
- data/spec/lib/ki/base_request_spec.rb +24 -24
- data/spec/lib/ki/helpers_spec.rb +1 -1
- data/spec/lib/ki/ki_app_spec.rb +13 -0
- data/spec/lib/ki/ki_config_spec.rb +16 -2
- data/spec/lib/ki/ki_spec.rb +11 -0
- data/spec/lib/ki/middleware/haml_compiler_spec.rb +6 -4
- data/spec/lib/ki/{modules/format_of_spec.rb → middleware/helpers/format_of_helper_spec.rb} +4 -1
- data/spec/lib/ki/model_spec.rb +14 -14
- data/spec/lib/ki/modules/model_helper_spec.rb +4 -0
- data/spec/lib/ki/orm_spec.rb +25 -25
- data/spec/spec_helper.rb +6 -4
- data/spec/util_spec.rb +2 -2
- metadata +36 -14
- data/spec/lib/ki/modules/model_helpers_spec.rb +0 -4
data/lib/ki/ki_app.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ki
|
2
|
+
class KiApp
|
3
|
+
include Middleware::Helpers::HamlCompiler
|
4
|
+
include Middleware::Helpers::View
|
5
|
+
|
6
|
+
def call(env)
|
7
|
+
path = view_exists?('404') ? view_path('404') : custom_view_path
|
8
|
+
html = render_haml_file(path).strip!
|
9
|
+
Rack::Response.new(html, 404).finish
|
10
|
+
end
|
11
|
+
|
12
|
+
def custom_view_path
|
13
|
+
File.join(File.dirname(__FILE__), 'views', '404.haml')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/ki/ki_cli.rb
CHANGED
@@ -12,24 +12,23 @@ module Ki
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.requies_ki_directory
|
15
|
-
unless File.
|
16
|
-
say
|
15
|
+
unless File.exist? 'config.ru'
|
16
|
+
say 'Working directory should be a ki app.'
|
17
17
|
exit 3
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
class AppGenerator < KiGenerator
|
23
|
-
|
24
23
|
argument :app_name
|
25
24
|
|
26
25
|
def prepare_dir
|
27
26
|
unless app_name =~ /^[a-zA-Z0-9-]*$/
|
28
|
-
say
|
27
|
+
say 'App name must contain only alphanumeric characters and -'
|
29
28
|
exit 1
|
30
29
|
end
|
31
30
|
|
32
|
-
if Dir.
|
31
|
+
if Dir.exist? app_name
|
33
32
|
say "#{app_name} already exists"
|
34
33
|
exit 2
|
35
34
|
end
|
@@ -38,14 +37,14 @@ module Ki
|
|
38
37
|
end
|
39
38
|
|
40
39
|
def create_app
|
41
|
-
directory(
|
40
|
+
directory('spec/examples/base', app_name)
|
42
41
|
|
43
42
|
# Set database names
|
44
43
|
config_file = File.read("#{app_name}/config.yml")
|
45
|
-
config_file.gsub!(
|
46
|
-
config_file.gsub!(
|
47
|
-
config_file.gsub!(
|
48
|
-
File.open("#{app_name}/config.yml",
|
44
|
+
config_file.gsub!('name: np_development', "name: #{app_name}_development")
|
45
|
+
config_file.gsub!('name: np_test', "name: #{app_name}_test")
|
46
|
+
config_file.gsub!('name: np', "name: #{app_name}")
|
47
|
+
File.open("#{app_name}/config.yml", 'w') { |file| file.puts config_file }
|
49
48
|
|
50
49
|
# Set rvm gemset name
|
51
50
|
`echo #{app_name} > #{app_name}/.ruby-gemset`
|
@@ -55,8 +54,8 @@ module Ki
|
|
55
54
|
class DevServer < KiGenerator
|
56
55
|
DEFAULT_PORT = 1337
|
57
56
|
|
58
|
-
argument :port, type: :numeric, desc:
|
59
|
-
desc
|
57
|
+
argument :port, type: :numeric, desc: 'port for ki server.', default: DEFAULT_PORT
|
58
|
+
desc 'Starts the ki server'
|
60
59
|
|
61
60
|
def start_server
|
62
61
|
KiGenerator.requies_ki_directory
|
data/lib/ki/ki_config.rb
CHANGED
@@ -6,25 +6,29 @@ module Ki
|
|
6
6
|
|
7
7
|
attr_reader :config, :environment
|
8
8
|
|
9
|
-
def read
|
9
|
+
def read(environment)
|
10
10
|
@environment = environment
|
11
11
|
@config = YAML.load_file(config_file_path)[environment]
|
12
|
+
@config['cors'] ||= true
|
12
13
|
end
|
13
14
|
|
14
15
|
def config_file_path
|
15
16
|
'config.yml'
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
-
|
19
|
+
def cors?
|
20
|
+
@config['cors']
|
21
|
+
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
def middleware
|
24
|
+
used_middleware = %w(ApiHandler CoffeeCompiler SassCompiler HamlCompiler
|
25
|
+
PublicFileServer)
|
26
|
+
used_middleware = @config['middleware'] if @config['middleware'].present?
|
24
27
|
|
25
|
-
|
28
|
+
# convert middleware to ruby object
|
29
|
+
used_middleware.map do |middleware|
|
26
30
|
Object.const_get('Ki').const_get('Middleware').const_get(middleware)
|
27
|
-
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def database
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Ki
|
2
2
|
module Middleware #:nodoc:
|
3
|
-
|
4
3
|
# Handles all API calls
|
5
4
|
#
|
6
5
|
# Any json request is considered an api call. A request is considered as json
|
@@ -11,7 +10,7 @@ module Ki
|
|
11
10
|
class ApiHandler
|
12
11
|
include BaseMiddleware
|
13
12
|
|
14
|
-
def call
|
13
|
+
def call(env)
|
15
14
|
req = BaseRequest.new env
|
16
15
|
if req.json?
|
17
16
|
resourcerize(req)
|
@@ -20,30 +19,30 @@ module Ki
|
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
def resourcerize
|
22
|
+
def resourcerize(req)
|
24
23
|
klass = req.to_ki_model_class
|
25
24
|
|
26
25
|
unless Model.descendants.include?(klass)
|
27
|
-
|
26
|
+
fail InvalidUrlError.new("invalid url '#{req.path}'", 404)
|
28
27
|
end
|
29
28
|
|
30
29
|
model = klass.new(req.to_action, req.params)
|
31
|
-
if req.params['redirect_to'].nil? # TODO document this
|
30
|
+
if req.params['redirect_to'].nil? # TODO: document this
|
32
31
|
render model
|
33
32
|
else
|
34
|
-
redirect_to req.params['redirect_to'] # TODO check for injection
|
33
|
+
redirect_to req.params['redirect_to'] # TODO: check for injection
|
35
34
|
end
|
36
35
|
rescue ApiError => e
|
37
36
|
render e
|
38
37
|
end
|
39
38
|
|
40
|
-
def redirect_to
|
39
|
+
def redirect_to(s)
|
41
40
|
resp = Rack::Response.new
|
42
41
|
resp.redirect(s)
|
43
42
|
resp.finish
|
44
43
|
end
|
45
44
|
|
46
|
-
def render
|
45
|
+
def render(r)
|
47
46
|
resp = Rack::Response.new(r.result.to_json, r.status)
|
48
47
|
resp['Content-Type'] = 'application/json'
|
49
48
|
resp.finish
|
@@ -3,12 +3,12 @@ module Ki
|
|
3
3
|
class CoffeeCompiler
|
4
4
|
include BaseMiddleware
|
5
5
|
|
6
|
-
def call
|
6
|
+
def call(env)
|
7
7
|
req = BaseRequest.new env
|
8
8
|
coffee_path = req.path.to_s[0...-3] + '.coffee'
|
9
9
|
if !public_file_exists?(req) && format_of(req) == 'js' && public_file_exists?(coffee_path)
|
10
10
|
js = CoffeeScript.compile(File.read(public_file_path(coffee_path)))
|
11
|
-
Rack::Response.new(js, 200, {
|
11
|
+
Rack::Response.new(js, 200, { 'Content-Type' => 'application/javascript' }).finish
|
12
12
|
else
|
13
13
|
@app.call env
|
14
14
|
end
|
@@ -3,20 +3,21 @@ module Ki
|
|
3
3
|
class DocGenerator < HamlCompiler
|
4
4
|
include BaseMiddleware
|
5
5
|
|
6
|
-
def call
|
6
|
+
def call(env)
|
7
7
|
req = BaseRequest.new env
|
8
8
|
if custom_check(req)
|
9
9
|
if view_exists?(req)
|
10
|
-
|
10
|
+
html = render_haml_file view_path(req)
|
11
11
|
else
|
12
|
-
|
12
|
+
html = render_haml_file custom_view_path
|
13
13
|
end
|
14
|
+
Rack::Response.new(html).finish
|
14
15
|
else
|
15
16
|
@app.call env
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
def custom_check
|
20
|
+
def custom_check(req)
|
20
21
|
req.doc?
|
21
22
|
end
|
22
23
|
|
@@ -2,35 +2,17 @@ module Ki
|
|
2
2
|
module Middleware
|
3
3
|
class HamlCompiler
|
4
4
|
include BaseMiddleware
|
5
|
+
include Helpers::HamlCompiler
|
5
6
|
|
6
|
-
def call
|
7
|
+
def call(env)
|
7
8
|
req = BaseRequest.new env
|
8
9
|
if view_exists?(req)
|
9
|
-
|
10
|
+
html = render_haml_file view_path(req)
|
11
|
+
Rack::Response.new(html).finish
|
10
12
|
else
|
11
13
|
@app.call env
|
12
14
|
end
|
13
15
|
end
|
14
|
-
|
15
|
-
def render_haml file_path
|
16
|
-
file_contents = File.read(file_path)
|
17
|
-
|
18
|
-
if view_exists? 'layout'
|
19
|
-
layout_contents = File.read(view_path('layout'))
|
20
|
-
else
|
21
|
-
layout_contents = "= yield"
|
22
|
-
end
|
23
|
-
|
24
|
-
html = haml(layout_contents).render do
|
25
|
-
haml(file_contents).render
|
26
|
-
end
|
27
|
-
|
28
|
-
Rack::Response.new(html).finish
|
29
|
-
end
|
30
|
-
|
31
|
-
def haml s
|
32
|
-
Haml::Engine.new("- extend Ki::Helpers\n" + s)
|
33
|
-
end
|
34
16
|
end
|
35
17
|
end
|
36
18
|
end
|
@@ -2,10 +2,10 @@ module Ki
|
|
2
2
|
module Middleware
|
3
3
|
module Helpers
|
4
4
|
module FormatOf
|
5
|
-
def format_of
|
5
|
+
def format_of(uri)
|
6
6
|
uri = uri.path if uri.class == BaseRequest
|
7
|
-
File.extname(URI.parse(uri).path).gsub('.','')
|
8
|
-
rescue URI::InvalidURIError
|
7
|
+
File.extname(URI.parse(uri).path).gsub('.', '')
|
8
|
+
rescue URI::InvalidURIError
|
9
9
|
''
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ki
|
2
|
+
module Middleware
|
3
|
+
module Helpers
|
4
|
+
module HamlCompiler
|
5
|
+
def render_haml_file(file_path, layout = true)
|
6
|
+
file_contents = File.read(file_path)
|
7
|
+
|
8
|
+
if layout && view_exists?('layout')
|
9
|
+
layout_contents = File.read(view_path('layout'))
|
10
|
+
else
|
11
|
+
layout_contents = '= yield'
|
12
|
+
end
|
13
|
+
|
14
|
+
html = render_haml(layout_contents).render do
|
15
|
+
render_haml(file_contents).render
|
16
|
+
end
|
17
|
+
|
18
|
+
html
|
19
|
+
end
|
20
|
+
|
21
|
+
def render_haml(s)
|
22
|
+
Haml::Engine.new("- extend Ki::Helpers\n" + s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -2,12 +2,12 @@ module Ki
|
|
2
2
|
module Middleware
|
3
3
|
module Helpers
|
4
4
|
module PublicFile
|
5
|
-
def public_file_exists?
|
5
|
+
def public_file_exists?(path)
|
6
6
|
path = path.path if path.class == BaseRequest
|
7
7
|
File.file?(public_file_path(path))
|
8
8
|
end
|
9
9
|
|
10
|
-
def public_file_path
|
10
|
+
def public_file_path(path)
|
11
11
|
path = path.path if path.class == BaseRequest
|
12
12
|
File.join(Ki::PUBLIC_PATH, path)
|
13
13
|
end
|
@@ -2,14 +2,14 @@ module Ki
|
|
2
2
|
module Middleware
|
3
3
|
module Helpers
|
4
4
|
module View
|
5
|
-
def view_exists?
|
5
|
+
def view_exists?(path)
|
6
6
|
path = path.path if path.class == BaseRequest
|
7
7
|
File.file?(view_path(path))
|
8
8
|
end
|
9
9
|
|
10
|
-
def view_path
|
10
|
+
def view_path(path)
|
11
11
|
path = path.path if path.class == BaseRequest
|
12
|
-
File.join(Ki::VIEWS_PATH, path +
|
12
|
+
File.join(Ki::VIEWS_PATH, path + '.haml')
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -3,13 +3,13 @@ module Ki
|
|
3
3
|
class SassCompiler
|
4
4
|
include BaseMiddleware
|
5
5
|
|
6
|
-
def call
|
6
|
+
def call(env)
|
7
7
|
req = BaseRequest.new env
|
8
8
|
sass_path = req.path.to_s[0...-4] + '.sass'
|
9
9
|
# if req ends with css and it does not exist, if a sass file exists instead
|
10
10
|
if !public_file_exists?(req) && format_of(req) == 'css' && public_file_exists?(sass_path)
|
11
|
-
eng = Sass::Engine.new(File.read(public_file_path(sass_path)), :
|
12
|
-
Rack::Response.new(eng.render, 200, {
|
11
|
+
eng = Sass::Engine.new(File.read(public_file_path(sass_path)), syntax: :sass)
|
12
|
+
Rack::Response.new(eng.render, 200, { 'Content-Type' => 'text/css' }).finish
|
13
13
|
else
|
14
14
|
@app.call env
|
15
15
|
end
|
data/lib/ki/model.rb
CHANGED
@@ -3,16 +3,17 @@ module Ki
|
|
3
3
|
extend QueryInterface
|
4
4
|
extend Restrictions
|
5
5
|
include Callbacks
|
6
|
-
include
|
6
|
+
include ModelHelper
|
7
7
|
|
8
8
|
attr_accessor :action, :result, :params, :status
|
9
9
|
|
10
|
-
def initialize
|
10
|
+
def initialize(action, params)
|
11
11
|
@action = action
|
12
12
|
@params = params
|
13
13
|
@status = 200
|
14
14
|
|
15
|
-
|
15
|
+
fail ForbiddenAction if forbidden_actions.include? @action
|
16
|
+
|
16
17
|
ccall
|
17
18
|
end
|
18
19
|
|
@@ -40,26 +41,24 @@ module Ki
|
|
40
41
|
|
41
42
|
def check_for_required_attributes
|
42
43
|
required_attributes.each do |ra|
|
43
|
-
|
44
|
-
|
44
|
+
unless @params.keys.include?(ra.to_s)
|
45
|
+
fail RequiredAttributeMissing, "#{ra} missing"
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
50
|
def check_for_unique_attributes
|
50
51
|
unique_attributes.each do |ua|
|
51
|
-
u = self.class.find({ua.to_s => @params[ua.to_s]})
|
52
|
-
unless u.empty?
|
53
|
-
raise AttributeNotUnique.new("#{ua.to_s} not unique")
|
54
|
-
end
|
52
|
+
u = self.class.find({ ua.to_s => @params[ua.to_s] })
|
53
|
+
fail AttributeNotUnique, "#{ua} not unique" unless u.empty?
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
57
|
def ccall
|
59
58
|
before_all
|
60
|
-
send "before_#{@action
|
59
|
+
send "before_#{@action}".to_sym
|
61
60
|
send @action.to_sym
|
62
|
-
send "after_#{@action
|
61
|
+
send "after_#{@action}".to_sym
|
63
62
|
after_all
|
64
63
|
end
|
65
64
|
|