ki 0.4.1 → 0.4.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +224 -15
- data/ki.gemspec +1 -2
- data/lib/ki.rb +1 -0
- data/lib/ki/api_error.rb +7 -2
- data/lib/ki/indifferent_hash.rb +11 -0
- data/lib/ki/orm.rb +5 -1
- data/lib/ki/version.rb +1 -1
- data/spec/examples/couch-lock/Gemfile.lock +1 -1
- data/spec/examples/couch-lock/app.rb +50 -5
- data/spec/examples/couch-lock/public/fonts/FontAwesome.otf +0 -0
- data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.eot +0 -0
- data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.svg +520 -0
- data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.ttf +0 -0
- data/spec/examples/couch-lock/public/fonts/fontawesome-webfont.woff +0 -0
- data/spec/examples/couch-lock/public/stylesheets/font-awesome.min.css +4 -0
- data/spec/examples/couch-lock/public/stylesheets/main.sass +7 -0
- data/spec/examples/couch-lock/public/stylesheets/pure-min.css +11 -0
- data/spec/examples/couch-lock/views/index.haml +53 -14
- data/spec/examples/json.northpole.ro/Gemfile.lock +1 -1
- data/spec/examples/json.northpole.ro/app.rb +3 -3
- data/spec/examples/todo/.ruby-gemset +1 -0
- data/spec/examples/todo/.ruby-version +1 -0
- data/spec/examples/todo/Gemfile +4 -0
- data/spec/examples/todo/app.rb +11 -0
- data/spec/examples/todo/config.ru +3 -0
- data/spec/examples/todo/config.yml +17 -0
- data/spec/examples/todo/public/favicon.ico +0 -0
- data/spec/examples/todo/public/javascripts/.gitkeep +0 -0
- data/spec/examples/todo/public/stylesheets/.gitkeep +0 -0
- data/spec/examples/todo/views/index.haml +1 -0
- data/spec/examples/todo/views/layout.haml +6 -0
- data/spec/lib/ki/indifferent_hash_spec.rb +10 -0
- metadata +44 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fecab0fa4fb36ca609b3858125f8966cb2c83b24
|
4
|
+
data.tar.gz: 374608a0b13d1bce947ac0e8d42facc78b7fa5dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 142a52569d62b87646811ee4f2ab16d7dc397427f495aaca1a8369d2d3632d7bd4f91fd50623114a94b8d57e265faf142b70fa29a6f1a719f3b1f9d9a8e16681
|
7
|
+
data.tar.gz: a75db7d74e8e7e816efa78ea57a573a613285e8bbea0f844f7006f69256ebc3e9136c46b035fac074d938ff36597ae8271cbcf32a6c68fd61d5ea65af425a074
|
data/Gemfile.lock
CHANGED
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
23
|
-
cd my-app
|
24
|
-
bundle
|
53
|
+
ki new todo
|
25
54
|
```
|
26
55
|
|
27
|
-
This will create the folder *
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
data/lib/ki/api_error.rb
CHANGED
@@ -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
|
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
|
data/lib/ki/orm.rb
CHANGED
@@ -9,7 +9,11 @@ module Ki
|
|
9
9
|
|
10
10
|
def establish_connection
|
11
11
|
@config = KiConfig.instance.database
|
12
|
-
|
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
|
data/lib/ki/version.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
52
|
+
run "killall -9 vlc"
|
23
53
|
else
|
24
|
-
|
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
|
-
|
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
|
-
`
|
84
|
+
run `kill \`ps ax | grep lockserver.UDPServer | grep -v grep | awk '{ print $1 }'\``
|
40
85
|
end
|
41
86
|
end
|
42
87
|
end
|