ki 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +224 -15
  4. data/ki.gemspec +1 -2
  5. data/lib/ki.rb +1 -0
  6. data/lib/ki/api_error.rb +7 -2
  7. data/lib/ki/indifferent_hash.rb +11 -0
  8. data/lib/ki/orm.rb +5 -1
  9. data/lib/ki/version.rb +1 -1
  10. data/spec/examples/couch-lock/Gemfile.lock +1 -1
  11. data/spec/examples/couch-lock/app.rb +50 -5
  12. data/spec/examples/couch-lock/public/fonts/FontAwesome.otf +0 -0
  13. data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.eot +0 -0
  14. data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.svg +520 -0
  15. data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.ttf +0 -0
  16. data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.woff +0 -0
  17. data/spec/examples/couch-lock/public/stylesheets/font-awesome.min.css +4 -0
  18. data/spec/examples/couch-lock/public/stylesheets/main.sass +7 -0
  19. data/spec/examples/couch-lock/public/stylesheets/pure-min.css +11 -0
  20. data/spec/examples/couch-lock/views/index.haml +53 -14
  21. data/spec/examples/json.northpole.ro/Gemfile.lock +1 -1
  22. data/spec/examples/json.northpole.ro/app.rb +3 -3
  23. data/spec/examples/todo/.ruby-gemset +1 -0
  24. data/spec/examples/todo/.ruby-version +1 -0
  25. data/spec/examples/todo/Gemfile +4 -0
  26. data/spec/examples/todo/app.rb +11 -0
  27. data/spec/examples/todo/config.ru +3 -0
  28. data/spec/examples/todo/config.yml +17 -0
  29. data/spec/examples/todo/public/favicon.ico +0 -0
  30. data/spec/examples/todo/public/javascripts/.gitkeep +0 -0
  31. data/spec/examples/todo/public/stylesheets/.gitkeep +0 -0
  32. data/spec/examples/todo/views/index.haml +1 -0
  33. data/spec/examples/todo/views/layout.haml +6 -0
  34. data/spec/lib/ki/indifferent_hash_spec.rb +10 -0
  35. metadata +44 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d3882f219cbe5267ace949b299161f8d7088de4
4
- data.tar.gz: dbd684f59faf3cb6ed83dcce014f7f6c024bd4b9
3
+ metadata.gz: fecab0fa4fb36ca609b3858125f8966cb2c83b24
4
+ data.tar.gz: 374608a0b13d1bce947ac0e8d42facc78b7fa5dd
5
5
  SHA512:
6
- metadata.gz: 906832115b4f414a7c78d00ca31bc9bcd4b1a1eb5f7e18e5f341a7794c364b6caf2738b9ae123b6a4afbca4d0328342512c66e3e38e920cacdf4fc34806015db
7
- data.tar.gz: 54f9f057d005f7ce0697b4584b3af94ceb5f0bcfdccb5d14282d19f1eeaa61dc9ceeb70a0c0179ded589898ca015f02b5ecc59b78e0e3628b9a8ce47e737af53
6
+ metadata.gz: 142a52569d62b87646811ee4f2ab16d7dc397427f495aaca1a8369d2d3632d7bd4f91fd50623114a94b8d57e265faf142b70fa29a6f1a719f3b1f9d9a8e16681
7
+ data.tar.gz: a75db7d74e8e7e816efa78ea57a573a613285e8bbea0f844f7006f69256ebc3e9136c46b035fac074d938ff36597ae8271cbcf32a6c68fd61d5ea65af425a074
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ki (0.4.1)
4
+ ki (0.4.2)
5
5
  bson_ext
6
6
  bundler (~> 1.5)
7
7
  coffee-script
data/README.md CHANGED
@@ -1,12 +1,37 @@
1
1
  # Ki Framework
2
2
 
3
- Tiny REST JSON ORM framework
3
+ Tiny REST JSON ORM framework.
4
4
 
5
- * rvm
6
- * mongodb
7
- * haml
8
- * sass
9
- * coffee
5
+ Ki's goal is to help you protoype your ideas blazing fast. It has a db backend
6
+ and provides a fullblown REST api on top.
7
+
8
+ ## TLDR
9
+
10
+ To create an api endpoint '/todo.json' with GET/POST/PATCH and restricting
11
+ DELETE, with title and description as required attributes, with db backend,
12
+ with a unique title, and before/after filters you would need to write:
13
+
14
+ ```ruby
15
+ class Todo < Ki::Model
16
+ requires :title, :description
17
+ unique :title
18
+ forbid :delete
19
+
20
+ def before_all
21
+ puts 'hello'
22
+ end
23
+
24
+ def before_create
25
+ params['created_at'] = Time.now.to_i
26
+ end
27
+
28
+ def after_find
29
+ if result['keywords'].include? 'food'
30
+ puts 'yummy'
31
+ end
32
+ end
33
+ end
34
+ ```
10
35
 
11
36
  ## Install
12
37
 
@@ -16,20 +41,42 @@ gem install ki
16
41
 
17
42
  ## Getting started
18
43
 
44
+ Learn by example. We will create the traditional 'hello world' app for web
45
+ development: the dreaded TODO app.
46
+
47
+ View the [code](https://github.com/mess110/ki/tree/master/spec/examples/todo) for
48
+ the final webapp.
49
+
19
50
  ### Creating a new app
20
51
 
21
52
  ```shell
22
- ki new my-app
23
- cd my-app
24
- bundle
53
+ ki new todo
25
54
  ```
26
55
 
27
- This will create the folder *my-app* containing a bare bones ki application.
56
+ This will create the folder *todo* containing a bare bones ki application. Your
57
+ app will look [like this](https://github.com/mess110/ki/tree/master/spec/examples/base).
58
+
59
+ App directory structure:
60
+
61
+ * public/
62
+ * javascripts/
63
+ * stylesheets/
64
+ * views/
65
+ * app.rb
66
+ * config.yml
67
+
68
+ The entry point for the app is *app.rb*. You will add most of your code there.
69
+ Views are in the *views* folder and you can find some database info in
70
+ *config.yml*.
28
71
 
29
72
  ```shell
73
+ cd todo
74
+ bundle
30
75
  rackup
31
76
  ```
32
77
 
78
+ *rackup* is the command which starts the webserver. The port will be displayed.
79
+
33
80
  ### Adding a view
34
81
 
35
82
  A view is a html page. By default, a view called 'index.haml' is created for
@@ -48,16 +95,178 @@ similar to haml.
48
95
 
49
96
  ### View layout
50
97
 
51
- TODO
98
+ If the file *views/layout.haml* exists, it will be used as a layout for all the
99
+ other haml files. The content of the route will be placed in the layout *yield*
100
+
101
+ *views/layout.haml*
102
+
103
+ ```haml
104
+ !!!
105
+ %html
106
+ %head
107
+ %title Ki Framework
108
+ %body
109
+ = yield
110
+ ```
111
+
112
+ *views/index.haml*
113
+
114
+ ```haml
115
+ %p Hello World!
116
+ ```
117
+
118
+ ### Helpers
119
+
120
+ To reduce complexity in your views, you can use helpers. Here we create a
121
+ *say_hello* method which we can use in *views/index.haml*.
122
+
123
+ *app.rb*
124
+
125
+ ```ruby
126
+ module Ki::Helpers
127
+ def say_hello
128
+ 'hello'
129
+ end
130
+ end
131
+ ```
132
+
133
+ *views/index.haml*
134
+
135
+ ```haml
136
+ %p= say_hello
137
+ ```
52
138
 
53
139
  ### Adding a resource
54
140
 
55
- TODO
141
+ Think of resources as the M in MVC. Except they also have routes attached.
142
+ All resources must inherit from Ki::Model. For example, to create a todo model
143
+ add the fallowing snippet to *app.rb*
144
+
145
+ ```ruby
146
+ class Todo < Ki::Model
147
+ end
148
+ ```
149
+
150
+ This will create the Todo resource and its corresponding routes. Each route is
151
+ mapped to a model method.
152
+
153
+ Method name | Verb | HTTP request|Required params|
154
+ ------------|------|-------------|---------------|
155
+ find |GET | /todo.json | |
156
+ create |POST | /todo.json | |
157
+ update |PATCH | /todo.json |id |
158
+ delete |DELETE| /todo.json |id |
159
+
160
+ Below is a curl example for creating a todo item. Notice the data sent in the
161
+ body request is a JSON string. It can take the shape of any valid JSON object.
162
+ All json objects will be stored in the database under the resource name. In our
163
+ case *todo*.
164
+
165
+ #### Create
166
+
167
+ ```shell
168
+ curl -X POST -d '{"title": "make a todo tutorial"}' http://localhost:9292/todo.json
169
+ ```
170
+
171
+ #### Get all
172
+
173
+ ```shell
174
+ curl -X GET http://localhost:9292/todo.json
175
+ ```
176
+
177
+ #### Get by id
178
+
179
+ ```shell
180
+ curl -X GET http://localhost:9292/todo.json?id=ITEM_ID
181
+ ```
182
+
183
+ #### Update
184
+
185
+ ```shell
186
+ curl -X PATCH -d '{"id": "ITEM_ID", "title": "finish the todo tutorial"}' http://localhost:9292/todo.json
187
+ ```
188
+
189
+ #### Delete
190
+
191
+ ```shell
192
+ curl -X DELETE -d http://localhost:9292/todo.json?id=ITEM_ID
193
+ ```
194
+
195
+ ### Required attributes
196
+
197
+ You can add mandatory attributes on resources with the *requires* method. It
198
+ takes one parameter or an array of parameters as an argument.
199
+
200
+ ```ruby
201
+ class Todo < Ki::Model
202
+ requires :title
203
+ end
204
+ ```
205
+
206
+ This will make sure a Todo item can not be saved or updated in the database
207
+ without a title attribute.
56
208
 
57
209
  ### Restricting resource requests
58
210
 
59
- TODO
211
+ Let's say you want to forbid access to deleting items. You can do that with
212
+ the *forbid* method.
213
+
214
+ ```ruby
215
+ class Todo < Ki::Model
216
+ forbid :delete
217
+ end
218
+ ```
219
+
220
+ ### Before/after callbacks
221
+
222
+ The framework has [these callbacks](https://github.com/mess110/ki/blob/master/lib/ki/modules/callbacks.rb).
223
+ Here is an example on how to use them:
224
+
225
+ ```ruby
226
+ class Todo < Ki::Model
227
+ def before_create
228
+ # do your stuff
229
+ end
230
+ end
231
+ ```
232
+
233
+ #### Accessing the json object within a callback
234
+
235
+ Before the request is sent to the client, you can look at the result through
236
+ the *result* method. Modifying it will change what the client receives.
237
+
238
+ ```ruby
239
+ class Todo < Ki::Model
240
+ def after_find
241
+ puts result
242
+ end
243
+ end
244
+ ```
245
+
246
+ ### Exceptions
247
+
248
+ A list of exceptions can be found [here](https://github.com/mess110/ki/blob/master/lib/ki/api_error.rb)
249
+
250
+ ```ruby
251
+ class Todo < Ki::Model
252
+ def before_all
253
+ ensure_authroization
254
+ end
255
+
256
+ private
257
+
258
+ def ensure_authorization
259
+ if params[:key] = 'secret-key'
260
+ raise UnauthorizedError.new
261
+ end
262
+ end
263
+ end
264
+ ```
265
+
266
+ ## Deploy
60
267
 
61
- ### Before/after filters
268
+ It has a *config.ru* file. Ki is based on *rack*. You can deploy anywhere (ex:
269
+ nginx, thin, apache, webrick).
62
270
 
63
- TODO
271
+ In the webserver config, just remember to point the virtual host to the
272
+ *public* directory.
data/ki.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["mess110@gmail.com"]
11
11
  spec.summary = %q{it said optional}
12
12
  spec.description = %q{it said optional}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/mess110/ki"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
@@ -28,7 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.add_runtime_dependency "mongo"
29
29
  spec.add_runtime_dependency "bson_ext"
30
30
 
31
-
32
31
  spec.add_development_dependency "rake"
33
32
  spec.add_development_dependency "rack-test"
34
33
  spec.add_development_dependency "rspec"
data/lib/ki.rb CHANGED
@@ -19,6 +19,7 @@ require 'ki/modules/view_helper'
19
19
  require 'ki/modules/format_of'
20
20
  require 'ki/modules/public_file_helper'
21
21
 
22
+ require 'ki/indifferent_hash'
22
23
  require 'ki/ki_config'
23
24
  require 'ki/helpers'
24
25
  require 'ki/orm'
@@ -16,8 +16,13 @@ module Ki
16
16
  class RequiredAttributeMissing < ApiError; end
17
17
  class AttributeNotUnique < ApiError; end
18
18
  class ForbiddenAction < ApiError
19
- def initialize
20
- super 'action forbidden', 400
19
+ def initialize s='forbidden', code=403
20
+ super s, code
21
+ end
22
+ end
23
+ class UnauthorizedError < ApiError
24
+ def initialize s='unauthroized', code=401
25
+ super s, code
21
26
  end
22
27
  end
23
28
  class PartialNotFoundError < ApiError
@@ -0,0 +1,11 @@
1
+ class IndifferentHash < Hash
2
+ def []=(key,val)
3
+ key = key.to_sym
4
+ super(key, val)
5
+ end
6
+
7
+ def [](*args)
8
+ args[0] = args[0].to_sym
9
+ super(*args)
10
+ end
11
+ end
@@ -9,7 +9,11 @@ module Ki
9
9
 
10
10
  def establish_connection
11
11
  @config = KiConfig.instance.database
12
- @connection = Mongo::Connection.new(@config['host'], @config['port'])
12
+ if ENV["MONGODB_URI"]
13
+ @connection = Mongo::Connection.new
14
+ else
15
+ @connection = Mongo::Connection.new(@config['host'], @config['port'])
16
+ end
13
17
  @db = @connection.db(@config['name'])
14
18
  self
15
19
  end
@@ -1,3 +1,3 @@
1
1
  module Ki
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../../..
3
3
  specs:
4
- ki (0.4.0)
4
+ ki (0.4.1)
5
5
  bson_ext
6
6
  bundler (~> 1.5)
7
7
  coffee-script
@@ -1,5 +1,35 @@
1
1
  require 'ki'
2
2
 
3
+ def run cmd
4
+ res = `DISPLAY=:0.0 #{cmd}`
5
+ puts res
6
+ res
7
+ end
8
+
9
+ module Ki
10
+ module Helpers
11
+ def display_status
12
+ res = run "xrandr | head -n 1 | awk '{ print $8 }'"
13
+ res.strip.to_i == 1920 ? 'cloned' : 'extended'
14
+ end
15
+
16
+ def vlc_running?
17
+ res = run "ps -ef | grep vlc | grep -v grep | head -n 1"
18
+ res.strip != ""
19
+ end
20
+
21
+ def couch_lock_running?
22
+ res = run "ps -ef | grep lockserver.UDPServer | grep -v grep | head -n 1"
23
+ res.strip != ""
24
+ end
25
+
26
+ def sound_output
27
+ res = run "pactl info | grep 'Default Sink' | grep hdmi"
28
+ res.strip == "" ? 'analog' : 'hdmi'
29
+ end
30
+ end
31
+ end
32
+
3
33
  class Monitors < Ki::Model
4
34
  forbid :create, :update, :delete
5
35
 
@@ -7,7 +37,7 @@ class Monitors < Ki::Model
7
37
  return if params["q"].nil?
8
38
  return unless ['c', 'e'].include? params["q"]
9
39
 
10
- `disper -#{params["q"]}`
40
+ run "disper -#{params["q"]}"
11
41
  end
12
42
  end
13
43
 
@@ -19,9 +49,9 @@ class Fireplace < Ki::Model
19
49
  return unless ['kill', 'start'].include? params["q"]
20
50
 
21
51
  if params["q"] == "kill"
22
- `killall -9 vlc`
52
+ run "killall -9 vlc"
23
53
  else
24
- `vlc https://www.youtube.com/watch?v=rH79BmeeM0o --fullscreen`
54
+ run "vlc https://www.youtube.com/watch?v=rH79BmeeM0o --fullscreen &"
25
55
  end
26
56
  end
27
57
  end
@@ -34,9 +64,24 @@ class Sound < Ki::Model
34
64
  return unless ['speakers', 'hdmi'].include? params["q"]
35
65
 
36
66
  if params["q"] == "speakers"
37
- `pacmd set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo`
67
+ run "pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo"
68
+ else
69
+ run "pactl set-default-sink alsa_output.pci-0000_01_00.1.hdmi-stereo-extra1"
70
+ end
71
+ end
72
+ end
73
+
74
+ class Jrobot < Ki::Model
75
+ forbid :create, :update, :delete
76
+
77
+ def after_find
78
+ return if params["q"].nil?
79
+ return unless ['listen', 'kill'].include? params["q"]
80
+
81
+ if params["q"] == "listen"
82
+ run `cd ../../../../CouchLockServer/; ./start.sh`
38
83
  else
39
- `pacmd set-default-sink alsa_output.pci-0000_01_00.1.hdmi-stereo-extra1`
84
+ run `kill \`ps ax | grep lockserver.UDPServer | grep -v grep | awk '{ print $1 }'\``
40
85
  end
41
86
  end
42
87
  end