ki 0.4.2 → 0.4.3

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +18 -2
  5. data/Rakefile +8 -0
  6. data/bin/ki +1 -1
  7. data/lib/ki/api_error.rb +15 -7
  8. data/lib/ki/base_request.rb +1 -1
  9. data/lib/ki/helpers.rb +10 -1
  10. data/lib/ki/ki_cli.rb +53 -32
  11. data/lib/ki/middleware.rb +14 -9
  12. data/lib/ki/modules/callbacks.rb +22 -20
  13. data/lib/ki/modules/format_of.rb +10 -6
  14. data/lib/ki/modules/model_helpers.rb +26 -24
  15. data/lib/ki/modules/public_file_helper.rb +12 -8
  16. data/lib/ki/modules/query_interface.rb +28 -26
  17. data/lib/ki/modules/restrictions.rb +34 -32
  18. data/lib/ki/modules/view_helper.rb +12 -8
  19. data/lib/ki/orm.rb +125 -2
  20. data/lib/ki/version.rb +1 -1
  21. data/spec/examples/base/.ruby-version +1 -1
  22. data/spec/examples/base/Gemfile +1 -2
  23. data/spec/examples/couch-lock/Gemfile +0 -1
  24. data/spec/examples/couch-lock/app.rb +52 -0
  25. data/spec/examples/couch-lock/public/doorbell-1.wav +0 -0
  26. data/spec/examples/couch-lock/public/fonts/glyphicons-halflings-regular.eot +0 -0
  27. data/spec/examples/couch-lock/public/fonts/glyphicons-halflings-regular.svg +229 -0
  28. data/spec/examples/couch-lock/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  29. data/spec/examples/couch-lock/public/fonts/glyphicons-halflings-regular.woff +0 -0
  30. data/spec/examples/couch-lock/public/javascripts/angular.min.js +247 -0
  31. data/spec/examples/couch-lock/public/javascripts/clApp.coffee +68 -0
  32. data/spec/examples/couch-lock/public/stylesheets/bootstrap-theme.min.css +5 -0
  33. data/spec/examples/couch-lock/public/stylesheets/bootstrap.min.css +5 -0
  34. data/spec/examples/couch-lock/public/stylesheets/main.sass +29 -0
  35. data/spec/examples/couch-lock/views/index.haml +57 -57
  36. data/spec/examples/couch-lock/views/layout.haml +25 -0
  37. data/spec/examples/couch-lock/views/settings.haml +26 -0
  38. data/spec/examples/couch-lock/views/shop.haml +23 -0
  39. data/spec/examples/couch-lock/views/wiki.haml +6 -0
  40. data/spec/examples/json.northpole.ro/Gemfile.lock +1 -1
  41. data/spec/examples/todo/.ruby-version +1 -1
  42. data/spec/examples/todo/Gemfile +0 -1
  43. data/spec/lib/ki/model_spec.rb +1 -1
  44. data/spec/lib/ki/modules/format_of_spec.rb +2 -2
  45. metadata +29 -7
  46. data/spec/examples/couch-lock/Gemfile.lock +0 -48
  47. data/spec/examples/couch-lock/public/stylesheets/pure-min.css +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fecab0fa4fb36ca609b3858125f8966cb2c83b24
4
- data.tar.gz: 374608a0b13d1bce947ac0e8d42facc78b7fa5dd
3
+ metadata.gz: 848983c889362ba630e00014d4b670342d59ac68
4
+ data.tar.gz: a34e3829a0b471ba4f2cf3e31c7c3f0ba1a82231
5
5
  SHA512:
6
- metadata.gz: 142a52569d62b87646811ee4f2ab16d7dc397427f495aaca1a8369d2d3632d7bd4f91fd50623114a94b8d57e265faf142b70fa29a6f1a719f3b1f9d9a8e16681
7
- data.tar.gz: a75db7d74e8e7e816efa78ea57a573a613285e8bbea0f844f7006f69256ebc3e9136c46b035fac074d938ff36597ae8271cbcf32a6c68fd61d5ea65af425a074
6
+ metadata.gz: b4c33d21423505f78dd4d20afa6bae4e8c42c6dafd79325290384db94f53162d346c6087c9b3e8fa4dace49dfa13f4be41c70b6e24cc6116bb5d1756e89c2117
7
+ data.tar.gz: 4c7442a2117142f8cd45a8e1c690ec6f7d42b7d7bc10cb0d96b71c8ca1fb2a6b891b12c6459f04dbb3ccb9e8c3b79e18faf94e1fbacd50d942b0b4b611a1283e
data/.gitignore CHANGED
@@ -8,3 +8,5 @@
8
8
 
9
9
  spec/examples/*/tmp
10
10
  spec/examples/*/log
11
+
12
+ /doc/*
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ki (0.4.2)
4
+ ki (0.4.3)
5
5
  bson_ext
6
6
  bundler (~> 1.5)
7
7
  coffee-script
data/README.md CHANGED
@@ -72,10 +72,11 @@ Views are in the *views* folder and you can find some database info in
72
72
  ```shell
73
73
  cd todo
74
74
  bundle
75
- rackup
75
+ ki server
76
76
  ```
77
77
 
78
- *rackup* is the command which starts the webserver. The port will be displayed.
78
+ *ki server* is the command which starts the webserver. By default it starts on
79
+ port 1337.
79
80
 
80
81
  ### Adding a view
81
82
 
@@ -270,3 +271,18 @@ nginx, thin, apache, webrick).
270
271
 
271
272
  In the webserver config, just remember to point the virtual host to the
272
273
  *public* directory.
274
+
275
+ ### Heroku deployment
276
+
277
+ ```shell
278
+ ki new heroku-ki
279
+ cd heroku-ki
280
+ bundle
281
+ git init
282
+ git add .
283
+ git commit -m 'initial commit'
284
+ heroku create
285
+ heroku config:set MONGODB_URI="mongodb://user:pass@mongo_url:mongo_port/db_name"
286
+ git push heroku master
287
+ heroku open
288
+ ```
data/Rakefile CHANGED
@@ -1,5 +1,13 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
+ require 'rdoc/task'
4
+
5
+ RDoc::Task.new do |rdoc|
6
+ rdoc.main = "README.md"
7
+ rdoc.rdoc_files.
8
+ include("README.md", "lib/**/*.rb")
9
+ rdoc.rdoc_dir = 'doc'
10
+ end
3
11
 
4
12
  RSpec::Core::RakeTask.new(:spec)
5
13
 
data/bin/ki CHANGED
@@ -4,4 +4,4 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
5
  require 'ki/ki_cli'
6
6
 
7
- KiCli.start(ARGV)
7
+ Ki::Cli::Main.start(ARGV)
@@ -1,5 +1,5 @@
1
1
  module Ki
2
- class ApiError < StandardError
2
+ class ApiError < StandardError #:nodoc:
3
3
  attr_reader :status
4
4
 
5
5
  def initialize body, status=400
@@ -12,20 +12,28 @@ module Ki
12
12
  end
13
13
  end
14
14
 
15
- class InvalidUrlError < ApiError; end
16
- class RequiredAttributeMissing < ApiError; end
17
- class AttributeNotUnique < ApiError; end
18
- class ForbiddenAction < ApiError
15
+ class InvalidUrlError < ApiError #:nodoc:
16
+ end
17
+
18
+ class RequiredAttributeMissing < ApiError #:nodoc:
19
+ end
20
+
21
+ class AttributeNotUnique < ApiError #:nodoc:
22
+ end
23
+
24
+ class ForbiddenAction < ApiError #:nodoc:
19
25
  def initialize s='forbidden', code=403
20
26
  super s, code
21
27
  end
22
28
  end
23
- class UnauthorizedError < ApiError
29
+
30
+ class UnauthorizedError < ApiError #:nodoc:
24
31
  def initialize s='unauthroized', code=401
25
32
  super s, code
26
33
  end
27
34
  end
28
- class PartialNotFoundError < ApiError
35
+
36
+ class PartialNotFoundError < ApiError #:nodoc:
29
37
  def initialize s
30
38
  super "partial #{s} not found", 404
31
39
  end
@@ -1,6 +1,6 @@
1
1
  module Ki
2
2
  class BaseRequest < Rack::Request
3
- include FormatOf
3
+ include Middleware::Helpers::FormatOf
4
4
 
5
5
  def root?
6
6
  path == '/'
@@ -1,4 +1,13 @@
1
1
  class String
2
+ # Converts a string to a class
3
+ #
4
+ # ==== Examples
5
+ #
6
+ # class User
7
+ # end
8
+ #
9
+ # "user".to_class == User
10
+ #
2
11
  def to_class
3
12
  chain = self.split "::"
4
13
  klass = Kernel
@@ -29,7 +38,7 @@ end
29
38
 
30
39
  module Ki
31
40
  module Helpers
32
- include ViewHelper
41
+ include Middleware::Helpers::View
33
42
 
34
43
  def css url
35
44
  render_haml "%link{:href => '#{url}', :rel => 'stylesheet'}"
@@ -1,46 +1,67 @@
1
1
  require 'thor'
2
2
 
3
- class KiGenerator < Thor::Group
4
- include Thor::Actions
3
+ module Ki
4
+ module Cli #:nodoc:
5
+ class KiGenerator < Thor::Group #:nodoc:
6
+ include Thor::Actions
5
7
 
6
- def self.source_root
7
- File.join(File.dirname(__FILE__), '..', '..')
8
- end
9
- end
8
+ def self.source_root
9
+ File.join(File.dirname(__FILE__), '..', '..')
10
+ end
11
+ end
10
12
 
11
- class AppGenerator < KiGenerator
13
+ class AppGenerator < KiGenerator
12
14
 
13
- argument :app_name
15
+ argument :app_name
14
16
 
15
- def prepare_dir
16
- unless app_name =~ /^[a-zA-Z0-9-]*$/
17
- say "App name must contain only alphanumeric characters and -"
18
- exit 1
19
- end
17
+ def prepare_dir
18
+ unless app_name =~ /^[a-zA-Z0-9-]*$/
19
+ say "App name must contain only alphanumeric characters and -"
20
+ exit 1
21
+ end
22
+
23
+ if Dir.exists? app_name
24
+ say "#{app_name} already exists"
25
+ exit 2
26
+ end
27
+
28
+ Dir.mkdir app_name
29
+ end
30
+
31
+ def create_app
32
+ directory("spec/examples/base", app_name)
20
33
 
21
- if Dir.exists? app_name
22
- say "#{app_name} already exists"
23
- exit 2
34
+ # Set database names
35
+ config_file = File.read("#{app_name}/config.yml")
36
+ config_file.gsub!("name: np_development", "name: #{app_name}_development")
37
+ config_file.gsub!("name: np_test", "name: #{app_name}_test")
38
+ config_file.gsub!("name: np", "name: #{app_name}")
39
+ File.open("#{app_name}/config.yml", "w") {|file| file.puts config_file}
40
+
41
+ # Set rvm gemset name
42
+ `echo #{app_name} > #{app_name}/.ruby-gemset`
43
+ end
24
44
  end
25
45
 
26
- Dir.mkdir app_name
27
- end
46
+ class DevServer < KiGenerator
47
+ DEFAULT_PORT = 1337
28
48
 
29
- def create_app
30
- directory("spec/examples/base", app_name)
49
+ argument :port, type: :numeric, desc: "port for ki server.", default: DEFAULT_PORT
50
+ desc "Starts the ki server"
31
51
 
32
- # Set database names
33
- config_file = File.read("#{app_name}/config.yml")
34
- config_file.gsub!("name: np_development", "name: #{app_name}_development")
35
- config_file.gsub!("name: np_test", "name: #{app_name}_test")
36
- config_file.gsub!("name: np", "name: #{app_name}")
37
- File.open("#{app_name}/config.yml", "w") {|file| file.puts config_file}
52
+ def start_server
53
+ unless File.exists? 'config.ru'
54
+ say "Working directory should be a ki app."
55
+ exit 3
56
+ end
38
57
 
39
- # Set rvm gemset name
40
- `echo #{app_name} > #{app_name}/.ruby-gemset`
41
- end
42
- end
58
+ `bundle exec rackup -o 0.0.0.0 -p #{port}`
59
+ end
60
+ end
43
61
 
44
- class KiCli < Thor
45
- register AppGenerator, :new, 'new [APP_NAME]', 'generate a new app'
62
+ class Main < Thor
63
+ register AppGenerator, :new, 'new [APP_NAME]', 'generate a new app'
64
+ register DevServer, :server, 'server [PORT]', "start the ki server. Default port is #{DevServer::DEFAULT_PORT}"
65
+ end
66
+ end
46
67
  end
@@ -1,9 +1,9 @@
1
1
  module Ki
2
- module Middleware
2
+ module Middleware #:nodoc:
3
3
  module BaseMiddleware
4
- include FormatOf
5
- include ViewHelper
6
- include PublicFileHelper
4
+ include Helpers::FormatOf
5
+ include Helpers::View
6
+ include Helpers::PublicFile
7
7
 
8
8
  def initialize app
9
9
  @app = app
@@ -29,9 +29,14 @@ module Ki
29
29
  def call env
30
30
  req = BaseRequest.new env
31
31
  if req.root?
32
- resp = Rack::Response.new
33
- resp.redirect('/index')
34
- resp.finish
32
+ if public_file_exists? 'index.html'
33
+ env['PATH_INFO'] = '/index.html'
34
+ Rack::File.new(Ki::PUBLIC_PATH).call env
35
+ else
36
+ resp = Rack::Response.new
37
+ resp.redirect('/index')
38
+ resp.finish
39
+ end
35
40
  else
36
41
  env['CONTENT_TYPE'] = 'application/json' if format_of(req) == 'json'
37
42
  @app.call env
@@ -80,7 +85,7 @@ module Ki
80
85
  coffee_path = req.path.to_s[0...-3] + '.coffee'
81
86
  if !public_file_exists?(req) && format_of(req) == 'js' && public_file_exists?(coffee_path)
82
87
  js = CoffeeScript.compile(File.read(public_file_path(coffee_path)))
83
- Rack::Response.new(js).finish
88
+ Rack::Response.new(js, 200, {"Content-Type" => "application/javascript"}).finish
84
89
  else
85
90
  @app.call env
86
91
  end
@@ -96,7 +101,7 @@ module Ki
96
101
  # if req ends with css and it does not exist, if a sass file exists instead
97
102
  if !public_file_exists?(req) && format_of(req) == 'css' && public_file_exists?(sass_path)
98
103
  eng = Sass::Engine.new(File.read(public_file_path(sass_path)), :syntax => :sass)
99
- Rack::Response.new(eng.render).finish
104
+ Rack::Response.new(eng.render, 200, {"Content-Type" => "text/css"}).finish
100
105
  else
101
106
  @app.call env
102
107
  end
@@ -1,33 +1,35 @@
1
1
  module Ki
2
- module Callbacks
3
- def before_all
4
- end
2
+ class Model
3
+ module Callbacks
4
+ def before_all
5
+ end
5
6
 
6
- def before_find
7
- end
7
+ def before_find
8
+ end
8
9
 
9
- def after_find
10
- end
10
+ def after_find
11
+ end
11
12
 
12
- def before_create
13
- end
13
+ def before_create
14
+ end
14
15
 
15
- def after_create
16
- end
16
+ def after_create
17
+ end
17
18
 
18
- def before_update
19
- end
19
+ def before_update
20
+ end
20
21
 
21
- def after_update
22
- end
22
+ def after_update
23
+ end
23
24
 
24
- def before_delete
25
- end
25
+ def before_delete
26
+ end
26
27
 
27
- def after_delete
28
- end
28
+ def after_delete
29
+ end
29
30
 
30
- def after_all
31
+ def after_all
32
+ end
31
33
  end
32
34
  end
33
35
  end
@@ -1,10 +1,14 @@
1
1
  module Ki
2
- module FormatOf
3
- def format_of uri
4
- uri = uri.path if uri.class == BaseRequest
5
- File.extname(URI.parse(uri).path).gsub('.','')
6
- rescue URI::InvalidURIError => e
7
- ''
2
+ module Middleware
3
+ module Helpers
4
+ module FormatOf
5
+ def format_of uri
6
+ uri = uri.path if uri.class == BaseRequest
7
+ File.extname(URI.parse(uri).path).gsub('.','')
8
+ rescue URI::InvalidURIError => e
9
+ ''
10
+ end
11
+ end
8
12
  end
9
13
  end
10
14
  end
@@ -1,35 +1,37 @@
1
1
  module Ki
2
- module ModelHelpers
3
- def get?
4
- @req.get?
5
- end
2
+ class Model
3
+ module ModelHelpers
4
+ def get?
5
+ @req.get?
6
+ end
6
7
 
7
- def post?
8
- @req.post?
9
- end
8
+ def post?
9
+ @req.post?
10
+ end
10
11
 
11
- def put?
12
- @req.put?
13
- end
12
+ def put?
13
+ @req.put?
14
+ end
14
15
 
15
- def delete?
16
- @req.delete?
17
- end
16
+ def delete?
17
+ @req.delete?
18
+ end
18
19
 
19
- def forbidden_actions
20
- []
21
- end
20
+ def forbidden_actions
21
+ []
22
+ end
22
23
 
23
- def required_attributes
24
- []
25
- end
24
+ def required_attributes
25
+ []
26
+ end
26
27
 
27
- def skipped_params
28
- []
29
- end
28
+ def skipped_params
29
+ []
30
+ end
30
31
 
31
- def unique_attributes
32
- []
32
+ def unique_attributes
33
+ []
34
+ end
33
35
  end
34
36
  end
35
37
  end