leif 0.0.1

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 (7) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +24 -0
  4. data/bin/leif +175 -0
  5. data/leif.gemspec +27 -0
  6. data/lib/leif/version.rb +3 -0
  7. metadata +91 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9d9a2a1fcb5a84d41c34a61fa2270c7750e06b4c
4
+ data.tar.gz: 2911bca79cac2758ade4ea92af8ae419d2e504be
5
+ SHA512:
6
+ metadata.gz: 12f5e0499fef091a3cda5a860c811197e48ff2293a86b1e2de68d4b08b749b5d6309846adca61928a5f2a52e109bc056115b30bc04cd7cb32f275a46e4058b86
7
+ data.tar.gz: 69e6e8c05f7cc51354a294b5b017562579a32a7a31aeeee2569b1c2239d323354841a8d126ff40f4e893cb71e846925f4fa560b2577f495b95335db71effc40b
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 CloudApp, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Leif
2
+
3
+ A hypermedia browser for the CloudApp Collection+JSON API.
4
+
5
+ ## Commands
6
+
7
+ ```
8
+ r
9
+ root
10
+ Go back to the root
11
+
12
+ f <rel>
13
+ follow <rel>
14
+ Follow link with the given relation.
15
+
16
+ b <username> [<password>]
17
+ basic <username> [<password>]
18
+ Authenticate with HTTP Basic and reload the current resource. Will be
19
+ prompted for password if it is omitted.
20
+
21
+ t <token>
22
+ token <token>
23
+ Authenticate using the given token and reload the current resource.
24
+ ```
data/bin/leif ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ class CollectionJsonResponse < SimpleDelegator
4
+ extend Forwardable
5
+
6
+ def_delegators :collection, :links, :link
7
+
8
+ def collection
9
+ Collection.new body
10
+ end
11
+
12
+ class Collection < SimpleDelegator
13
+ def initialize(body)
14
+ super body.fetch('collection')
15
+ end
16
+
17
+ def links
18
+ return [] unless has_key?('links')
19
+ fetch('links').map {|link| Link.new(link) }
20
+ end
21
+
22
+ def link(relation)
23
+ links.find {|link| link.relation == relation }
24
+ end
25
+ end
26
+
27
+ class Link
28
+ attr_accessor :relation, :href
29
+
30
+ def initialize(link)
31
+ @relation = link.fetch('rel')
32
+ @href = link.fetch('href')
33
+ end
34
+ end
35
+ end
36
+
37
+ def conn
38
+ @conn ||= Faraday.new(url: 'https://api.getcloudapp.com') do |config|
39
+ # config.response :logger
40
+ config.response :json, :content_type => /\bjson$/
41
+ config.adapter Faraday.default_adapter
42
+ end
43
+ end
44
+
45
+ def make_request(uri)
46
+ @response = CollectionJsonResponse.new(conn.get(uri))
47
+ end
48
+
49
+ def get_root
50
+ make_request '/'
51
+ end
52
+
53
+ def retry_request
54
+ make_request @response.env[:url].request_uri
55
+ end
56
+
57
+ def section(banner)
58
+ puts "-- #{banner} --"
59
+ output = Output.new(1)
60
+ yield output
61
+ output.print '[empty]' if output.empty?
62
+ output.print
63
+ end
64
+
65
+ class Output
66
+ attr_reader :level, :io
67
+ def empty?() @empty end
68
+
69
+ def initialize(level, io = $stdout)
70
+ @level = level
71
+ @io = io
72
+ @empty = true
73
+ end
74
+
75
+ def print(line = '')
76
+ print_lines Array(line)
77
+ end
78
+
79
+ def print_lines(lines)
80
+ @empty = false
81
+ lines.each do |line|
82
+ io.puts(indentation + line)
83
+ end
84
+ end
85
+
86
+ def indentation
87
+ ' ' * level
88
+ end
89
+ end
90
+
91
+ def print_response
92
+ section 'Request' do |out|
93
+ out.print "#{@response.env[:method].upcase} #{@response.env[:url]}"
94
+ out.print_lines @response.env[:request_headers].map {|header, value|
95
+ "#{header}: #{value}"
96
+ }
97
+ end
98
+
99
+ section 'Response' do |out|
100
+ out.print_lines @response.headers.map {|header, value|
101
+ "#{header}: #{value}"
102
+ }
103
+ end
104
+
105
+ section 'Body' do |out|
106
+ out.print_lines JSON.pretty_generate(@response.body).lines
107
+ end
108
+
109
+ section 'Options' do |out|
110
+ if @response.headers['www-authenticate']
111
+ out.print 'Re-request using HTTP Basic Auth'
112
+ end
113
+ out.print "Links: #{link_relations}" unless link_relations.empty?
114
+ out.print 'Go to root'
115
+ end
116
+ end
117
+
118
+ def link_relations
119
+ @response.links.map(&:relation).join(', ')
120
+ end
121
+
122
+ def request_basic_authentication(username, password = :ask)
123
+ password = ask('Password: ') {|q| q.echo = '*' } if password == :ask
124
+ conn.basic_auth username, password
125
+ retry_request
126
+ end
127
+
128
+ def request_token_authentication(token = '2x033S09401z300E')
129
+ conn.headers['Authorization'] = "Token token=#{token.inspect}"
130
+ retry_request
131
+ end
132
+
133
+ def follow_link(relation = :ask)
134
+ relation = ask('Relation: ') if relation == :ask
135
+ make_request @response.link(relation).href
136
+ end
137
+
138
+ def print_help
139
+ puts 'Help goes here'
140
+ end
141
+
142
+ def get_next_action
143
+ command, args = ask_for_action
144
+ case command
145
+ when 'r', 'root' then get_root
146
+ when 'f', 'follow' then follow_link(*args)
147
+ when 'b', 'basic' then request_basic_authentication(*args)
148
+ when 't', 'token' then request_token_authentication(*args)
149
+ when '?', 'help' then print_help; get_next_action
150
+ when 'q', 'quit' then exit
151
+ else puts 'Try again.'; get_next_action
152
+ end
153
+ end
154
+
155
+ def ask_for_action
156
+ input = ask('> ') {|q| q.readline = true }.split(/\s/)
157
+ [ input.first, input[1..-1] ]
158
+ end
159
+
160
+ trap('INT') { puts; exit }
161
+
162
+ get_root
163
+ loop do
164
+ print_response
165
+ get_next_action
166
+ end
167
+
168
+ BEGIN {
169
+ require 'delegate'
170
+ require 'forwardable'
171
+ require 'highline/import'
172
+ require 'json'
173
+ require 'faraday'
174
+ require 'faraday_middleware'
175
+ }
data/leif.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'leif/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'leif'
7
+ spec.version = Leif::VERSION
8
+ spec.summary = 'Explore the CloudApp API'
9
+ spec.description = 'A hypermedia browser for the CloudApp Collection+JSON API.'
10
+ spec.authors = ['Larry Marburger']
11
+ spec.email = 'larry@marburger.cc'
12
+ spec.homepage = 'https://github.com/cloudapp/leif'
13
+ spec.licenses = ['MIT']
14
+
15
+ spec.add_dependency 'faraday', '~> 0.8.8'
16
+ spec.add_dependency 'faraday_middleware', '~> 0.9.0'
17
+ spec.add_dependency 'highline', '~> 1.6.19'
18
+
19
+ spec.bindir = 'bin'
20
+ spec.executables = ['leif']
21
+
22
+ spec.files = %w(LICENSE README.md leif.gemspec)
23
+ spec.files += Dir.glob('lib/**/*.rb')
24
+ spec.files += Dir.glob('bin/*')
25
+
26
+ spec.required_rubygems_version = '>= 1.3.6'
27
+ end
@@ -0,0 +1,3 @@
1
+ module Leif
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: leif
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Larry Marburger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.8
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.8
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: highline
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.19
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.19
55
+ description: A hypermedia browser for the CloudApp Collection+JSON API.
56
+ email: larry@marburger.cc
57
+ executables:
58
+ - leif
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - LICENSE
63
+ - README.md
64
+ - leif.gemspec
65
+ - bin/leif
66
+ - lib/leif/version.rb
67
+ homepage: https://github.com/cloudapp/leif
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: 1.3.6
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.0.2
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Explore the CloudApp API
91
+ test_files: []