typekit-client 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +350 -0
- data/Rakefile +7 -0
- data/bin/typekit +146 -0
- data/lib/typekit.rb +13 -0
- data/lib/typekit/client.rb +38 -0
- data/lib/typekit/configuration.rb +16 -0
- data/lib/typekit/configuration/base.rb +21 -0
- data/lib/typekit/configuration/default.rb +34 -0
- data/lib/typekit/connection.rb +10 -0
- data/lib/typekit/connection/adaptor.rb +13 -0
- data/lib/typekit/connection/adaptor/standard.rb +32 -0
- data/lib/typekit/connection/dispatcher.rb +17 -0
- data/lib/typekit/connection/request.rb +23 -0
- data/lib/typekit/connection/response.rb +20 -0
- data/lib/typekit/core.rb +16 -0
- data/lib/typekit/helper.rb +43 -0
- data/lib/typekit/parser.rb +14 -0
- data/lib/typekit/parser/json.rb +13 -0
- data/lib/typekit/parser/yaml.rb +13 -0
- data/lib/typekit/processor.rb +38 -0
- data/lib/typekit/routing.rb +9 -0
- data/lib/typekit/routing/map.rb +43 -0
- data/lib/typekit/routing/node.rb +5 -0
- data/lib/typekit/routing/node/base.rb +45 -0
- data/lib/typekit/routing/node/collection.rb +34 -0
- data/lib/typekit/routing/node/operation.rb +32 -0
- data/lib/typekit/routing/node/root.rb +8 -0
- data/lib/typekit/routing/node/scope.rb +19 -0
- data/lib/typekit/routing/proxy.rb +17 -0
- data/lib/typekit/version.rb +3 -0
- data/spec/cassettes/index_kits_ok.yml +16 -0
- data/spec/cassettes/index_kits_unauthorized.yml +16 -0
- data/spec/cassettes/show_families_calluna_found.yml +16 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/rest_helper.rb +22 -0
- data/spec/typekit/client_spec.rb +36 -0
- data/spec/typekit/configuration_spec.rb +34 -0
- data/spec/typekit/connection/adaptor_spec.rb +24 -0
- data/spec/typekit/connection/dispatcher_spec.rb +36 -0
- data/spec/typekit/connection/request_spec.rb +13 -0
- data/spec/typekit/helper_spec.rb +93 -0
- data/spec/typekit/processor_spec.rb +34 -0
- data/spec/typekit/routing/map_spec.rb +106 -0
- data/spec/typekit/routing/node_spec.rb +40 -0
- data/typekit-client.gemspec +33 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c787138c7a90aa58f94a0f9cfd0080aeac67440d
|
4
|
+
data.tar.gz: 24df2e9aa560fb343e385198510af8c235afa72e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6adc44648829ecd93949689f00765376f61a9d8f7b6b3cd5e5976220dabb229c7a359ed26c12e8c9f46b7095fa928010d1732a32b88744131701cbebb688b2f9
|
7
|
+
data.tar.gz: 5adb42620a3c05627243b0e834ab12249a56cc62f48c0afe9ed5c87135f9ddc2a4fa03a206b3bc0d2106819027e701b75b0470d15194eea72eef06cf617d4235
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
## Typekit 0.0.2 (May 28, 2014)
|
2
|
+
* Renamed the gem into `typekit-client` (still `require 'typekit'`).
|
3
|
+
* Rewrote the whole library (refactoring, preparing for new features).
|
4
|
+
* Implemented a DSL for describing the resources provided by Typekit.
|
5
|
+
* Introduced a client-side verification of user requests.
|
6
|
+
|
7
|
+
## Typekit 0.0.1 (May 16, 2014)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright 2014 Ivan Ukhov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,350 @@
|
|
1
|
+
# Typekit Client
|
2
|
+
A Ruby library for accessing the [Typekit API](https://typekit.com/docs/api).
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
`Ruby >= 2.1` is required. Make sure you have it installed:
|
6
|
+
```bash
|
7
|
+
$ ruby -v
|
8
|
+
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
|
9
|
+
```
|
10
|
+
|
11
|
+
In case you don’t:
|
12
|
+
```bash
|
13
|
+
$ curl -sSL https://get.rvm.io | bash
|
14
|
+
$ rvm install 2.1
|
15
|
+
```
|
16
|
+
|
17
|
+
Add the gem into your `Gemfile`:
|
18
|
+
```ruby
|
19
|
+
gem 'typekit-client', require: 'typekit'
|
20
|
+
```
|
21
|
+
|
22
|
+
Then run `bundler`:
|
23
|
+
```bash
|
24
|
+
$ bundle
|
25
|
+
```
|
26
|
+
|
27
|
+
In order to interact with the Typekit API, one should have a valid API token.
|
28
|
+
You can generate such a token [here](https://typekit.com/account/tokens).
|
29
|
+
For convenience, let us create a shortcut for it:
|
30
|
+
```bash
|
31
|
+
$ export tk_token=YOUR_TOKEN_GOES_HERE
|
32
|
+
```
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
Here is the basic setup in a Ruby script:
|
36
|
+
```ruby
|
37
|
+
require 'typekit'
|
38
|
+
|
39
|
+
client = Typekit::Client.new(token: ENV['tk_token'])
|
40
|
+
```
|
41
|
+
|
42
|
+
And here is how to run it, assuming you name your script `app.rb`:
|
43
|
+
```bash
|
44
|
+
$ bundle exec ruby app.rb
|
45
|
+
```
|
46
|
+
|
47
|
+
The main method of `client` is `perform(action, *path, parameters = {})`.
|
48
|
+
The arguments are as follows:
|
49
|
+
* `action` is the action that you would like to perform on a resource, and
|
50
|
+
it can be one of `:index`, `:show`, `:create`, `:update`, or `:delete`;
|
51
|
+
* `*path` refers to an arbitrary number of arguments needed to identify
|
52
|
+
the desired resource (a plenty of examples are given below), and it
|
53
|
+
always begins with one of `:families`, `:kits`, or `:libraries`;
|
54
|
+
* `parameters` is a hash of parameters needed to perform the action.
|
55
|
+
|
56
|
+
`perform` has an alias for each of the actions: `index(*path, parameters = {})`,
|
57
|
+
`show(*path, parameters = {})`, `create(*path, parameters = {})`, and so on.
|
58
|
+
The result of a method call is returned as a hash, and its content is exactly
|
59
|
+
what the Typekit API sends back to `client`. The only exception is when
|
60
|
+
the API returns an error, in which case an appropriate exception is being
|
61
|
+
raised.
|
62
|
+
|
63
|
+
Before sending the actual request to the Typekit API, the library checks
|
64
|
+
whether the resource given by `*path` makes sense and, if it does, whether
|
65
|
+
`action` can be performed on that resource. So, if you receive an exception,
|
66
|
+
check out the [API reference](https://typekit.com/docs/api/).
|
67
|
+
|
68
|
+
Now, let us have a look at some typical use cases. For clarity, the code
|
69
|
+
below makes use of the following auxiliary function:
|
70
|
+
```ruby
|
71
|
+
def p(data)
|
72
|
+
puts JSON.pretty_generate(data)
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
### Show all kits
|
77
|
+
Code:
|
78
|
+
```ruby
|
79
|
+
p client.index(:kits)
|
80
|
+
```
|
81
|
+
|
82
|
+
Output:
|
83
|
+
```json
|
84
|
+
{
|
85
|
+
"kits": [
|
86
|
+
{
|
87
|
+
"id": "bas4cfe",
|
88
|
+
"link": "/api/v1/json/kits/bas4cfe"
|
89
|
+
},
|
90
|
+
...
|
91
|
+
]
|
92
|
+
}
|
93
|
+
```
|
94
|
+
|
95
|
+
### Show the description of a variant of a font family
|
96
|
+
Code:
|
97
|
+
```ruby
|
98
|
+
p client.show(:families, 'vcsm', 'i9')
|
99
|
+
```
|
100
|
+
|
101
|
+
Output:
|
102
|
+
```json
|
103
|
+
{
|
104
|
+
"variation": {
|
105
|
+
"id": "vcsm:i9",
|
106
|
+
"name": "Proxima Nova Black Italic",
|
107
|
+
"family": {
|
108
|
+
"id": "vcsm",
|
109
|
+
"link": "/api/v1/json/families/vcsm",
|
110
|
+
"name": "Proxima Nova"
|
111
|
+
},
|
112
|
+
"font_style": "italic",
|
113
|
+
"font_variant": "normal",
|
114
|
+
"font_weight": "900",
|
115
|
+
...
|
116
|
+
}
|
117
|
+
}
|
118
|
+
```
|
119
|
+
|
120
|
+
### Show the font families in the trial library with pagination
|
121
|
+
Code:
|
122
|
+
```ruby
|
123
|
+
p client.show(:libraries, 'trial', page: 10, per_page: 5)
|
124
|
+
```
|
125
|
+
|
126
|
+
Output:
|
127
|
+
```json
|
128
|
+
{
|
129
|
+
"library": {
|
130
|
+
"id": "trial",
|
131
|
+
"link": "/api/v1/json/libraries/trial",
|
132
|
+
"name": "Trial Library",
|
133
|
+
"families": [
|
134
|
+
{
|
135
|
+
"id": "qnhl",
|
136
|
+
"link": "/api/v1/json/families/qnhl",
|
137
|
+
"name": "Caliban Std"
|
138
|
+
},
|
139
|
+
{
|
140
|
+
"id": "vybr",
|
141
|
+
"link": "/api/v1/json/families/vybr",
|
142
|
+
"name": "Calluna"
|
143
|
+
},
|
144
|
+
...
|
145
|
+
],
|
146
|
+
"pagination": {
|
147
|
+
"count": 261,
|
148
|
+
"on": "families",
|
149
|
+
"page": 10,
|
150
|
+
"page_count": 53,
|
151
|
+
"per_page": 5
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
```
|
156
|
+
|
157
|
+
### Create a new kit
|
158
|
+
Code:
|
159
|
+
```ruby
|
160
|
+
p result = client.create(:kits, name: 'Megakit', domains: 'localhost')
|
161
|
+
kit_id = result['kit']['id']
|
162
|
+
```
|
163
|
+
|
164
|
+
Output:
|
165
|
+
```json
|
166
|
+
{
|
167
|
+
"kit": {
|
168
|
+
"id": "izw0qiq",
|
169
|
+
"name": "Megakit",
|
170
|
+
"analytics": false,
|
171
|
+
"badge": true,
|
172
|
+
"domains": [
|
173
|
+
"localhost"
|
174
|
+
],
|
175
|
+
"families": [
|
176
|
+
|
177
|
+
]
|
178
|
+
}
|
179
|
+
}
|
180
|
+
```
|
181
|
+
|
182
|
+
### Disable the badge of a kit
|
183
|
+
Code:
|
184
|
+
```ruby
|
185
|
+
p client.update(:kits, kit_id, badge: false)
|
186
|
+
```
|
187
|
+
|
188
|
+
Output:
|
189
|
+
```json
|
190
|
+
{
|
191
|
+
"kit": {
|
192
|
+
"id": "izw0qiq",
|
193
|
+
"name": "Megakit",
|
194
|
+
"analytics": false,
|
195
|
+
"badge": false,
|
196
|
+
"domains": [
|
197
|
+
"localhost"
|
198
|
+
],
|
199
|
+
"families": [
|
200
|
+
|
201
|
+
]
|
202
|
+
}
|
203
|
+
}
|
204
|
+
```
|
205
|
+
|
206
|
+
### Look up the id of a font family by its slug
|
207
|
+
Code:
|
208
|
+
```ruby
|
209
|
+
p result = client.show(:families, 'proxima-nova')
|
210
|
+
family_id = result['family']['id']
|
211
|
+
```
|
212
|
+
|
213
|
+
Output:
|
214
|
+
```json
|
215
|
+
{
|
216
|
+
"family": {
|
217
|
+
"id": "vcsm",
|
218
|
+
"link": "/api/v1/json/families/vcsm"
|
219
|
+
}
|
220
|
+
}
|
221
|
+
```
|
222
|
+
|
223
|
+
### Add a font family into a kit
|
224
|
+
Code:
|
225
|
+
```ruby
|
226
|
+
p client.update(:kits, kit_id, families: { "0" => { id: family_id } })
|
227
|
+
```
|
228
|
+
|
229
|
+
Output:
|
230
|
+
```json
|
231
|
+
{
|
232
|
+
"kit": {
|
233
|
+
"id": "nys8sny",
|
234
|
+
"name": "Megakit",
|
235
|
+
"analytics": false,
|
236
|
+
"badge": false,
|
237
|
+
"domains": [
|
238
|
+
"localhost"
|
239
|
+
],
|
240
|
+
"families": [
|
241
|
+
{
|
242
|
+
"id": "vcsm",
|
243
|
+
"name": "Proxima Nova",
|
244
|
+
"slug": "proxima-nova",
|
245
|
+
"css_names": [
|
246
|
+
"proxima-nova-1",
|
247
|
+
"proxima-nova-2"
|
248
|
+
],
|
249
|
+
...
|
250
|
+
}
|
251
|
+
]
|
252
|
+
}
|
253
|
+
}
|
254
|
+
```
|
255
|
+
|
256
|
+
### Delete a kit
|
257
|
+
Command:
|
258
|
+
```ruby
|
259
|
+
p client.delete(:kits, kit_id)
|
260
|
+
```
|
261
|
+
|
262
|
+
Output:
|
263
|
+
```json
|
264
|
+
{
|
265
|
+
"ok": true
|
266
|
+
}
|
267
|
+
```
|
268
|
+
|
269
|
+
## Command-line Interface (CLI)
|
270
|
+
There is a simple CLI provided in order to demonstrate the usage of the
|
271
|
+
library and to give the ability to perform basic operations without writing
|
272
|
+
any code. The tool is called `typekit`, and it should get installed along
|
273
|
+
with the gem. Try running:
|
274
|
+
```
|
275
|
+
$ typekit -h
|
276
|
+
Usage: typekit [options] [command]
|
277
|
+
|
278
|
+
Required options:
|
279
|
+
-t, --token TOKEN Set the API token
|
280
|
+
|
281
|
+
Other options:
|
282
|
+
-v, --version VERSION Set the API version
|
283
|
+
-f, --format FORMAT Set the data format
|
284
|
+
-h, --help Show this message
|
285
|
+
```
|
286
|
+
|
287
|
+
Alternatively, you can install `typekit` in the `bin` directory of your
|
288
|
+
project using the following command:
|
289
|
+
```bash
|
290
|
+
$ bundle binstubs typekit
|
291
|
+
```
|
292
|
+
|
293
|
+
The tool has two modes: normal and interactive. If `command` is provided,
|
294
|
+
the tool executes only that particular command and terminates:
|
295
|
+
```
|
296
|
+
$ typekit -t $tk_token index kits
|
297
|
+
{
|
298
|
+
"kits": [
|
299
|
+
{
|
300
|
+
"id": "bas4cfe",
|
301
|
+
"link": "/api/v1/json/kits/bas4cfe"
|
302
|
+
},
|
303
|
+
...
|
304
|
+
]
|
305
|
+
}
|
306
|
+
$
|
307
|
+
```
|
308
|
+
|
309
|
+
If `command` is not provided, the tool gives a command prompt wherein one
|
310
|
+
can enter multiple commands:
|
311
|
+
```
|
312
|
+
$ typekit -t $tk_token
|
313
|
+
Type 'help' for help and 'exit' to exit.
|
314
|
+
> help
|
315
|
+
Usage: <action> <resource> [parameters]
|
316
|
+
|
317
|
+
<action> index, show, create, update, or delete
|
318
|
+
<resource> a list separated by whitespaces
|
319
|
+
[parameters] a JSON-encoded hash (optional)
|
320
|
+
|
321
|
+
Examples:
|
322
|
+
index kits
|
323
|
+
show kits bas4cfe families vcsm
|
324
|
+
show families vcsm i9
|
325
|
+
show libraries trial { "page": 10, "per_page": 5 }
|
326
|
+
create kits { "name": "Megakit", "domains": "localhost" }
|
327
|
+
update kits bas4cfe { "name": "Ultrakit" }
|
328
|
+
delete kits bas4cfe
|
329
|
+
> index kits
|
330
|
+
{
|
331
|
+
"kits": [
|
332
|
+
{
|
333
|
+
"id": "bas4cfe",
|
334
|
+
"link": "/api/v1/json/kits/bas4cfe"
|
335
|
+
},
|
336
|
+
...
|
337
|
+
]
|
338
|
+
}
|
339
|
+
> exit
|
340
|
+
Bye.
|
341
|
+
$
|
342
|
+
```
|
343
|
+
|
344
|
+
## Contributing
|
345
|
+
|
346
|
+
1. Fork it ( https://github.com/IvanUkhov/typekit-client/fork )
|
347
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
348
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
349
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
350
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/typekit
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
4
|
+
|
5
|
+
require 'typekit'
|
6
|
+
require 'optparse'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
class Controller
|
10
|
+
def initialize(**options)
|
11
|
+
@client = Typekit::Client.new(**options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def process(command)
|
15
|
+
action, path, parameters = parse(command)
|
16
|
+
print @client.perform(action, path, parameters)
|
17
|
+
rescue Exception => e
|
18
|
+
puts e
|
19
|
+
end
|
20
|
+
|
21
|
+
def help
|
22
|
+
puts <<-HELP
|
23
|
+
Usage: <action> <resource> [parameters]
|
24
|
+
|
25
|
+
<action> show, create, update, or delete
|
26
|
+
<resource> a list separated by whitespaces
|
27
|
+
[parameters] a JSON-encoded hash (optional)
|
28
|
+
|
29
|
+
Examples:
|
30
|
+
index kits
|
31
|
+
show kits bas4cfe families vcsm
|
32
|
+
show families vcsm i9
|
33
|
+
show libraries trial { "page": 10, "per_page": 5 }
|
34
|
+
create kits { "name": "Megakit", "domains": "localhost" }
|
35
|
+
update kits bas4cfe { "name": "Ultrakit" }
|
36
|
+
delete kits bas4cfe
|
37
|
+
HELP
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def print(output)
|
43
|
+
puts JSON.pretty_generate(output)
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse(command)
|
47
|
+
parameters = extract_parameters!(command)
|
48
|
+
|
49
|
+
chunks = command.split(/\s+/).compact.reject(&:empty?)
|
50
|
+
action, path = chunks[0], chunks[1..-1]
|
51
|
+
|
52
|
+
raise 'Missing action name' if action.nil?
|
53
|
+
raise 'Invalid action name' unless action =~ /^\w+$/
|
54
|
+
|
55
|
+
raise 'Missing resource name' if path.empty?
|
56
|
+
unless path.all?{ |chunk| chunk =~ /^[-\w\d]+$/ }
|
57
|
+
raise 'Invalid resource name'
|
58
|
+
end
|
59
|
+
|
60
|
+
[ action, path, parameters ]
|
61
|
+
end
|
62
|
+
|
63
|
+
def extract_parameters!(command)
|
64
|
+
if command =~ /(?<parameters>{.*})\s*$/
|
65
|
+
parameters = JSON.parse(Regexp.last_match(:parameters))
|
66
|
+
raise unless parameters.is_a?(Hash)
|
67
|
+
command.gsub!(/{.*}/, '')
|
68
|
+
parameters
|
69
|
+
else
|
70
|
+
{}
|
71
|
+
end
|
72
|
+
rescue
|
73
|
+
raise 'Invalid parameters'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
options = {}
|
78
|
+
|
79
|
+
parser = OptionParser.new do |o|
|
80
|
+
o.banner = 'Usage: typekit [options] [command]'
|
81
|
+
|
82
|
+
o.separator ''
|
83
|
+
o.separator 'Required options:'
|
84
|
+
|
85
|
+
o.on('-t', '--token TOKEN', 'Set the API token') do |value|
|
86
|
+
options[:token] = value
|
87
|
+
end
|
88
|
+
|
89
|
+
o.separator ''
|
90
|
+
o.separator 'Other options:'
|
91
|
+
|
92
|
+
o.on('-v', '--version VERSION', 'Set the API version') do |value|
|
93
|
+
options[:version] = value
|
94
|
+
end
|
95
|
+
|
96
|
+
o.on('-f', '--format FORMAT', 'Set the data format') do |value|
|
97
|
+
options[:format] = value
|
98
|
+
end
|
99
|
+
|
100
|
+
o.on_tail('-h', '--help', 'Show this message') do
|
101
|
+
raise
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
begin
|
106
|
+
parser.parse!
|
107
|
+
rescue
|
108
|
+
puts parser
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
|
112
|
+
begin
|
113
|
+
controller = Controller.new(options)
|
114
|
+
rescue Exception => e
|
115
|
+
puts e
|
116
|
+
exit
|
117
|
+
end
|
118
|
+
|
119
|
+
unless ARGV.empty?
|
120
|
+
controller.process(ARGV.join(' '))
|
121
|
+
exit
|
122
|
+
end
|
123
|
+
|
124
|
+
puts %{Type 'help' for help and 'exit' to exit.}
|
125
|
+
|
126
|
+
loop do
|
127
|
+
begin
|
128
|
+
print '> '
|
129
|
+
command = $stdin.gets.strip
|
130
|
+
next if command.empty?
|
131
|
+
case command
|
132
|
+
when 'exit'
|
133
|
+
break
|
134
|
+
when 'help'
|
135
|
+
controller.help
|
136
|
+
else
|
137
|
+
controller.process(command)
|
138
|
+
end
|
139
|
+
rescue Interrupt
|
140
|
+
break
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
puts 'Bye.'
|
145
|
+
|
146
|
+
# vim: set ft=ruby
|