leif 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5dcc95800bc2d5d1ae86cd703bfbe9cc45fada5c
4
- data.tar.gz: 0f19f4caffd24aa042d345ebcc6c92a240201b9a
3
+ metadata.gz: 5fde83f5fbfd332f246ef59ca53fb8c7ba9d1027
4
+ data.tar.gz: 49965583dbd38fa276145668ece11702fe5c676f
5
5
  SHA512:
6
- metadata.gz: c9ca62217fa3b5b7032fcb21ddbb351dc59e0d4fd2e725e5883b59ebc7c76fce2bd39877f4dc3c7035d27af54fec50039d24df791ef7b49b2ee7db36d381032f
7
- data.tar.gz: 1bc16991a37bf09fe812e7003e998cdd215d56babf3455d119f3ab63dee1321d0747bf147dd08a941971c19402474c9f8f22eaf266451bf9723ccd7b9339ffb1
6
+ metadata.gz: 846ac3499f51b81c6f39da25559e29878f57697e2c28a4135afe27e1a47b6c505e42ffdeff0ddd42d285c911d00e870fddc884b5f51bf45e6fcc7f7a5906e2e0
7
+ data.tar.gz: 112adf4af67199102be748649edddfc9f835b329d427ed1f169c68f183b9ebc2fe9c5cdf5e7024dbb5685413f9b396c18eafe54d35c1e061af560cc23a5010ee
data/README.md CHANGED
@@ -16,3 +16,38 @@ A hypermedia browser for the CloudApp Collection+JSON API.
16
16
 
17
17
  - `token` <u>token</u>:
18
18
  Authenticate using the given token and reload the current resource.
19
+
20
+ ## Example
21
+
22
+ The UI is weak at this point and not very intuitive. To get started, here's a
23
+ sample workflow. It should give you a general overview of what's possible.
24
+
25
+ > follow authorization
26
+
27
+ > basic arthur@dent.com
28
+ Password: *****
29
+
30
+ > token <token copied from response body>
31
+
32
+ > follow drops
33
+ > follow next
34
+ > follow first
35
+
36
+ > create
37
+
38
+ Name (empty to submit): name
39
+ Value: CloudApp
40
+
41
+ Name (empty to submit): bookmark_url
42
+ Value: http://getcloudapp.com
43
+
44
+ Name (empty to submit):
45
+
46
+ > root
47
+ > follow drops
48
+ > update
49
+
50
+ Name (empty to submit): name
51
+ Value: The Guide
52
+
53
+ Name (empty to submit):
data/bin/leif CHANGED
@@ -3,10 +3,11 @@
3
3
  class CollectionJsonResponse < SimpleDelegator
4
4
  extend Forwardable
5
5
 
6
- def_delegators :collection, :links, :link
6
+ def_delegators :collection, :href, :links, :link, :items,
7
+ :template, :fill_template_field, :fill_template, :submit_template
7
8
 
8
9
  def collection
9
- Collection.new body
10
+ @collection ||= Collection.new(body)
10
11
  end
11
12
 
12
13
  class Collection < SimpleDelegator
@@ -14,6 +15,10 @@ class CollectionJsonResponse < SimpleDelegator
14
15
  super body.fetch('collection')
15
16
  end
16
17
 
18
+ def href
19
+ fetch('href')
20
+ end
21
+
17
22
  def links
18
23
  return [] unless has_key?('links')
19
24
  fetch('links').map {|link| Link.new(link) }
@@ -22,6 +27,26 @@ class CollectionJsonResponse < SimpleDelegator
22
27
  def link(relation)
23
28
  links.find {|link| link.relation == relation }
24
29
  end
30
+
31
+ def template
32
+ @template ||= Item.new(fetch('template'))
33
+ end
34
+
35
+ def fill_template_field(name, value)
36
+ template[name] = value
37
+ end
38
+
39
+ def fill_template(item)
40
+ item.to_hash.each do |name, value|
41
+ p [name, value]
42
+ fill_template_field name, value
43
+ end
44
+ end
45
+
46
+ def items
47
+ return [] unless has_key?('items')
48
+ fetch('items').map {|item| Item.new(item) }
49
+ end
25
50
  end
26
51
 
27
52
  class Link
@@ -32,10 +57,39 @@ class CollectionJsonResponse < SimpleDelegator
32
57
  @href = link.fetch('href')
33
58
  end
34
59
  end
60
+
61
+ class Item
62
+ attr_accessor :item
63
+
64
+ def initialize(item)
65
+ @item = item
66
+ end
67
+
68
+ def href
69
+ @item.fetch('href')
70
+ end
71
+
72
+ def data
73
+ @item.fetch('data')
74
+ end
75
+
76
+ def []=(name, value)
77
+ datum = data.find {|datum| datum['name'] == name }
78
+ return unless datum
79
+ datum['value'] = value
80
+ end
81
+
82
+ def to_hash
83
+ data.each_with_object({}) do |datum, data|
84
+ data[datum['name']] = datum['value']
85
+ end
86
+ end
87
+ end
35
88
  end
36
89
 
37
90
  def conn
38
91
  @conn ||= Faraday.new(url: 'https://api.getcloudapp.com') do |config|
92
+ config.request :url_encoded
39
93
  config.response :logger, logger
40
94
  config.response :json, :content_type => /\bjson$/
41
95
  config.adapter Faraday.default_adapter
@@ -55,9 +109,10 @@ def reset_debug_output
55
109
  debug_output.truncate 0
56
110
  end
57
111
 
58
- def make_request(uri)
112
+ def make_request(uri, data = {}, method = :unset)
113
+ method = data.empty? ? :get : :post if method == :unset
59
114
  reset_debug_output
60
- @response = CollectionJsonResponse.new(conn.get(uri))
115
+ @response = CollectionJsonResponse.new(conn.send(method, uri, data))
61
116
  end
62
117
 
63
118
  def get_root
@@ -69,11 +124,11 @@ def retry_request
69
124
  end
70
125
 
71
126
  def section(banner)
127
+ puts
72
128
  puts "-- #{banner} --"
73
129
  output = Output.new(1)
74
130
  yield output
75
131
  output.print '[empty]' if output.empty?
76
- output.print
77
132
  end
78
133
 
79
134
  class Output
@@ -129,7 +184,8 @@ def link_relations
129
184
  @response.links.map(&:relation).join(', ')
130
185
  end
131
186
 
132
- def request_basic_authentication(username, password = :ask)
187
+ def request_basic_authentication(username = :ask, password = :ask)
188
+ username = ask('Username: ') if username == :ask
133
189
  password = ask('Password: ') {|q| q.echo = '*' } if password == :ask
134
190
  conn.basic_auth username, password
135
191
  retry_request
@@ -145,6 +201,58 @@ def follow_link(relation = :ask)
145
201
  make_request @response.link(relation).href
146
202
  end
147
203
 
204
+ def create_item
205
+ loop do
206
+ section 'Create Item' do |out|
207
+ out.print_lines JSON.pretty_generate(@response.template.item).lines
208
+ end
209
+
210
+ puts
211
+ puts 'Fill the template to create a new item.'
212
+ name = ask('Name (empty to submit): ')
213
+ break if name.empty?
214
+ value = ask('Value: ')
215
+
216
+ @response.fill_template_field name, value
217
+ end
218
+
219
+ make_request @response.collection.href, @response.template.to_hash
220
+ end
221
+
222
+ def update_item
223
+ item = @response.collection.items.find do |item|
224
+ section 'Item' do |out|
225
+ out.print_lines JSON.pretty_generate(item.item).lines
226
+ end
227
+
228
+ puts
229
+ response = ask('Select this item to update [y,n]? ') do |q|
230
+ q.character = true
231
+ q.validate = /\A[yn]\Z/
232
+ end
233
+
234
+ response == 'y'
235
+ end
236
+
237
+ @response.fill_template item
238
+
239
+ loop do
240
+ section 'Update Item' do |out|
241
+ out.print_lines JSON.pretty_generate(@response.template.item).lines
242
+ end
243
+
244
+ puts
245
+ puts 'Fill the template to update the item.'
246
+ name = ask('Name (empty to submit): ')
247
+ break if name.empty?
248
+ value = ask('Value: ')
249
+
250
+ @response.fill_template_field name, value
251
+ end
252
+
253
+ make_request item.href, @response.template.to_hash, :put
254
+ end
255
+
148
256
  def print_debug
149
257
  section 'Debug' do |out|
150
258
  debug_output.rewind
@@ -160,12 +268,18 @@ def print_help
160
268
  follow <rel>:
161
269
  Follow link with the given relation.
162
270
 
163
- basic <username> [<password>]:
271
+ template [<name>=<value>...]:
272
+ Fill the template with the given name/value pairs and submit.
273
+
274
+ basic [<username> [<password>]]:
164
275
  Authenticate with HTTP Basic and reload the current resource. Will be
165
- prompted for password if it is omitted.
276
+ prompted for username and password if omitted.
166
277
 
167
278
  token <token>:
168
279
  Authenticate using the given token and reload the current resource.
280
+
281
+ debug:
282
+ Print debug output from the previous HTTP request and response.
169
283
  EOS
170
284
  end
171
285
 
@@ -174,6 +288,8 @@ def get_next_action
174
288
  case command
175
289
  when 'r', 'root' then get_root
176
290
  when 'f', 'follow' then follow_link(*args)
291
+ when 'create' then create_item
292
+ when 'update' then update_item
177
293
  when 'b', 'basic' then request_basic_authentication(*args)
178
294
  when 't', 'token' then request_token_authentication(*args)
179
295
  when 'd', 'debug' then print_debug; get_next_action
@@ -184,6 +300,7 @@ def get_next_action
184
300
  end
185
301
 
186
302
  def ask_for_action
303
+ puts
187
304
  input = ask('> ') {|q| q.readline = true }.split(/\s/)
188
305
  [ input.first, input[1..-1] ]
189
306
  end
data/lib/leif/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Leif
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
data/man/leif.1 CHANGED
@@ -23,8 +23,12 @@ Go back to the root
23
23
  Follow link with the given relation\.
24
24
  .
25
25
  .TP
26
- \fBbasic\fR \fIusername\fR [\fIpassword\fR]
27
- Authenticate with HTTP Basic and reload the current resource\. Will be prompted for password if it is omitted\.
26
+ \fBtemplate\fR [\fIname\fR=\fIvalue\fR\.\.\.]
27
+ Fill the template with the given name/value pairs and submit\.
28
+ .
29
+ .TP
30
+ \fBbasic\fR [\fIusername\fR [\fIpassword\fR]]
31
+ Authenticate with HTTP Basic and reload the current resource\. Will be prompted for username and password if omitted\.
28
32
  .
29
33
  .TP
30
34
  \fBtoken\fR \fItoken\fR
@@ -33,4 +37,86 @@ Authenticate using the given token and reload the current resource\.
33
37
  .TP
34
38
  \fBdebug\fR
35
39
  Print debug output from the previous HTTP request and response\.
40
+ .
41
+ .SH "EXAMPLES"
42
+ Follow a rel=account link:
43
+ .
44
+ .IP "" 4
45
+ .
46
+ .nf
47
+
48
+ > follow account
49
+ .
50
+ .fi
51
+ .
52
+ .IP "" 0
53
+ .
54
+ .P
55
+ Use HTTP Basic authentication and reload the current resource:
56
+ .
57
+ .IP "" 4
58
+ .
59
+ .nf
60
+
61
+ > basic
62
+ Username: arthur@dent\.com
63
+ Password: ********
64
+ .
65
+ .fi
66
+ .
67
+ .IP "" 0
68
+ .
69
+ .P
70
+ Set token authentication:
71
+ .
72
+ .IP "" 4
73
+ .
74
+ .nf
75
+
76
+ > token abc123def456
77
+ .
78
+ .fi
79
+ .
80
+ .IP "" 0
81
+ .
82
+ .P
83
+ Create a new item filling the \fBname\fR and \fBbookmark_url\fR fields:
84
+ .
85
+ .IP "" 4
86
+ .
87
+ .nf
88
+
89
+ > create
90
+
91
+ Name (empty to submit): name
92
+ Value: CloudApp
93
+
94
+ Name (empty to submit): bookmark_url
95
+ Value: http://getcloudapp\.com
96
+
97
+ Name (empty to submit):
98
+ .
99
+ .fi
100
+ .
101
+ .IP "" 0
102
+ .
103
+ .P
104
+ Update an item filling the \fBpassword\fR field:
105
+ .
106
+ .IP "" 4
107
+ .
108
+ .nf
109
+
110
+ > update
111
+
112
+ Select this item to update [y,n]? y
113
+
114
+ Name (empty to submit): password
115
+ Value: towel
116
+
117
+ Name (empty to submit):
118
+ .
119
+ .fi
120
+ .
121
+ .IP "" 0
36
122
 
data/man/leif.1.html CHANGED
@@ -63,6 +63,7 @@
63
63
  <a href="#SYNOPSIS">SYNOPSIS</a>
64
64
  <a href="#DESCRIPTION">DESCRIPTION</a>
65
65
  <a href="#INTERACTIVE-COMMANDS">INTERACTIVE COMMANDS</a>
66
+ <a href="#EXAMPLES">EXAMPLES</a>
66
67
  </div>
67
68
 
68
69
  <ol class='man-decor man-head man head'>
@@ -91,13 +92,58 @@ programs.</p>
91
92
  <dl>
92
93
  <dt class="flush"><code>root</code></dt><dd><p>Go back to the root</p></dd>
93
94
  <dt><code>follow</code> <var>rel</var></dt><dd><p>Follow link with the given relation.</p></dd>
94
- <dt><code>basic</code> <var>username</var> [<var>password</var>]</dt><dd><p>Authenticate with HTTP Basic and reload the current resource. Will be
95
- prompted for password if it is omitted.</p></dd>
95
+ <dt><code>template</code> [<var>name</var>=<var>value</var>...]</dt><dd><p>Fill the template with the given name/value pairs and submit.</p></dd>
96
+ <dt><code>basic</code> [<var>username</var> [<var>password</var>]]</dt><dd><p>Authenticate with HTTP Basic and reload the current resource. Will be
97
+ prompted for username and password if omitted.</p></dd>
96
98
  <dt><code>token</code> <var>token</var></dt><dd><p>Authenticate using the given token and reload the current resource.</p></dd>
97
99
  <dt class="flush"><code>debug</code></dt><dd><p>Print debug output from the previous HTTP request and response.</p></dd>
98
100
  </dl>
99
101
 
100
102
 
103
+ <h2 id="EXAMPLES">EXAMPLES</h2>
104
+
105
+ <p>Follow a rel=account link:</p>
106
+
107
+ <pre><code>&gt; follow account
108
+ </code></pre>
109
+
110
+ <p>Use HTTP Basic authentication and reload the current resource:</p>
111
+
112
+ <pre><code>&gt; basic
113
+ Username: arthur@dent.com
114
+ Password: ********
115
+ </code></pre>
116
+
117
+ <p>Set token authentication:</p>
118
+
119
+ <pre><code>&gt; token abc123def456
120
+ </code></pre>
121
+
122
+ <p>Create a new item filling the <code>name</code> and <code>bookmark_url</code> fields:</p>
123
+
124
+ <pre><code>&gt; create
125
+
126
+ Name (empty to submit): name
127
+ Value: CloudApp
128
+
129
+ Name (empty to submit): bookmark_url
130
+ Value: http://getcloudapp.com
131
+
132
+ Name (empty to submit):
133
+ </code></pre>
134
+
135
+ <p>Update an item filling the <code>password</code> field:</p>
136
+
137
+ <pre><code>&gt; update
138
+
139
+ Select this item to update [y,n]? y
140
+
141
+ Name (empty to submit): password
142
+ Value: towel
143
+
144
+ Name (empty to submit):
145
+ </code></pre>
146
+
101
147
 
102
148
  <ol class='man-decor man-foot man foot'>
103
149
  <li class='tl'></li>
data/man/leif.1.ronn CHANGED
@@ -18,12 +18,54 @@ programs.
18
18
  - `follow` <rel>:
19
19
  Follow link with the given relation.
20
20
 
21
- - `basic` <username> [<password>]:
21
+ - `template` [<name>=<value>...]:
22
+ Fill the template with the given name/value pairs and submit.
23
+
24
+ - `basic` [<username> [<password>]]:
22
25
  Authenticate with HTTP Basic and reload the current resource. Will be
23
- prompted for password if it is omitted.
26
+ prompted for username and password if omitted.
24
27
 
25
28
  - `token` <token>:
26
29
  Authenticate using the given token and reload the current resource.
27
30
 
28
31
  - `debug`:
29
32
  Print debug output from the previous HTTP request and response.
33
+
34
+ ## EXAMPLES
35
+
36
+ Follow a rel=account link:
37
+
38
+ > follow account
39
+
40
+ Use HTTP Basic authentication and reload the current resource:
41
+
42
+ > basic
43
+ Username: arthur@dent.com
44
+ Password: ********
45
+
46
+ Set token authentication:
47
+
48
+ > token abc123def456
49
+
50
+ Create a new item filling the `name` and `bookmark_url` fields:
51
+
52
+ > create
53
+
54
+ Name (empty to submit): name
55
+ Value: CloudApp
56
+
57
+ Name (empty to submit): bookmark_url
58
+ Value: http://getcloudapp.com
59
+
60
+ Name (empty to submit):
61
+
62
+ Update an item filling the `password` field:
63
+
64
+ > update
65
+
66
+ Select this item to update [y,n]? y
67
+
68
+ Name (empty to submit): password
69
+ Value: towel
70
+
71
+ Name (empty to submit):
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leif
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Larry Marburger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-07 00:00:00.000000000 Z
11
+ date: 2013-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday