pi 0.1.13

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.
data/lib/cli/usage.rb ADDED
@@ -0,0 +1,53 @@
1
+ class PI::Cli::Runner
2
+
3
+ def basic_usage
4
+ "Usage: pi [options] command [<args>] [command_options]\n" +
5
+ "Try 'pi help [command]' or 'pi help options' for more information."
6
+ end
7
+
8
+ def display_usage
9
+ if @usage
10
+ say @usage_error if @usage_error
11
+ say "Usage: #{@usage}"
12
+ return
13
+ elsif @verb_usage
14
+ say @verb_usage
15
+ return
16
+ end
17
+ say command_usage
18
+ end
19
+
20
+ def command_usage
21
+ <<-USAGE
22
+
23
+ #{basic_usage}
24
+
25
+ Currently available pi commands are:
26
+
27
+ User
28
+ pi login [url] Login
29
+ pi logout Logs current user out of the system
30
+ pi info List system information
31
+ pi user Display user information
32
+ pi targets List available targets infomation
33
+ pi password [newpassword] Change the password for the current user
34
+ pi github [name] Bind to the github account
35
+ pi runtimes Display the supported runtimes of the system
36
+ pi frameworks Display the supported frameworks of the system
37
+ pi version Display version information
38
+ pi help [command] Get general help or help on a specific command
39
+ pi help options Get help on available options
40
+
41
+ Project
42
+ projects List created projects
43
+ create-project [projectname] Create a new project
44
+ delete-project [projectname] Delete the project
45
+ project-events [projectname] List the event info for the project
46
+ project-tags [projectname] List the tags for the project
47
+ project-commits [projectname] List the commit log for the project
48
+ project-apps [projectname] List the applications for the project
49
+ upload [projectname] Upload the war package for java project
50
+ USAGE
51
+
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ module PI
2
+ module Cli
3
+ VERSION = '0.1.13'
4
+ end
5
+ end
data/lib/pi.rb ADDED
@@ -0,0 +1,3 @@
1
+ module PI; end
2
+
3
+ require 'pi/client'
data/lib/pi/client.rb ADDED
@@ -0,0 +1,250 @@
1
+ require "uri"
2
+ require 'rubygems'
3
+ require 'json/pure'
4
+ require 'open-uri'
5
+
6
+ require File.expand_path('../const', __FILE__)
7
+
8
+ class PI::Client
9
+
10
+ def self.version
11
+ PI::VERSION
12
+ end
13
+
14
+ attr_reader :target, :host, :auth_token
15
+ attr_accessor :trace
16
+
17
+ # Error codes
18
+ PI_HTTP_ERROR_CODES = [ 400, 500 ]
19
+
20
+ # Errors
21
+ class BadTarget < RuntimeError; end
22
+ class AuthError < RuntimeError; end
23
+ class TargetError < RuntimeError; end
24
+ class NotFound < RuntimeError; end
25
+ class BadResponse < RuntimeError; end
26
+ class HTTPException < RuntimeError; end
27
+
28
+
29
+ def initialize(target_urls=PI::DEFAULT_TARGET, auth_token=nil)
30
+ target_urls = "http://#{target_urls}" unless /^https?/ =~ target_urls
31
+ target_urls = target_urls.gsub(/\/+$/, '')
32
+ @target = target_urls
33
+ @auth_token = auth_token
34
+ end
35
+
36
+ #####################################################
37
+ # Users
38
+ #####################################################
39
+
40
+ def login(user, password)
41
+ status, body, headers = json_post("#{PI::TOKEN_PATH}", {:password => password,:userName => user})
42
+ response_info = json_parse(body)
43
+ if response_info
44
+ @auth_token = response_info[:token]
45
+ end
46
+ end
47
+
48
+ def info
49
+ json_get(PI::INFO_PATH)
50
+ end
51
+
52
+ def user_info
53
+ json_get(PI::USER_PATH)
54
+ end
55
+
56
+ def github_info
57
+ json_get("#{PI::USER_PATH}/github")
58
+ end
59
+
60
+ def targets
61
+ json_get("#{PI::USER_PATH}/targets")
62
+ end
63
+
64
+ def password(newpassword)
65
+ status, body, headers = json_post("#{PI::USER_PATH}/password/#{newpassword}",{:newpass => newpassword})
66
+ end
67
+
68
+ def github(manifest={})
69
+ json_post("#{PI::USER_PATH}/bind",manifest)
70
+ end
71
+
72
+ def runtimes
73
+ json_get("#{PI::INFO_PATH}/runtimes")
74
+ end
75
+
76
+ def frameworks(runtime)
77
+ json_get("#{PI::INFO_PATH}/frameworks/#{runtime}")
78
+ end
79
+
80
+ #####################################################
81
+ # projects
82
+ #####################################################
83
+
84
+ def projects
85
+ json_get("#{PI::PROJECT_PATH}/list")
86
+ end
87
+
88
+ def create_project(name, manifest={})
89
+ status, body, headers = json_post("#{PI::PROJECT_PATH}/create", manifest)
90
+ end
91
+
92
+ def delete_project(projectname)
93
+ http_delete("#{PI::PROJECT_PATH}/delete/#{projectname}",'application/json')
94
+ end
95
+
96
+ def upload(manifest={})
97
+ status, body, headers = http_post("#{PI::PROJECT_PATH}/upload", manifest)
98
+ response_info = json_parse(body)
99
+ end
100
+
101
+ def project_events(projectname)
102
+ json_get("#{PI::PROJECT_PATH}/events/#{projectname}")
103
+ end
104
+
105
+ def project_tags(projectname)
106
+ json_get("#{PI::PROJECT_PATH}/tags/#{projectname}")
107
+ end
108
+
109
+ def project_commits(projectname,tag)
110
+ json_get("#{PI::PROJECT_PATH}/commitinfo/#{projectname}/#{tag}")
111
+ end
112
+
113
+ def project_apps(projectname)
114
+ json_get("#{PI::PROJECT_PATH}/apps/#{projectname}")
115
+ end
116
+
117
+ ######################################################
118
+
119
+ private
120
+
121
+ def json_get(url)
122
+ status, body, headers = http_get(url, 'application/json')
123
+ if body.empty?
124
+ body = nil
125
+ end
126
+ json_parse(body)
127
+ rescue JSON::ParserError
128
+ raise BadResponse, "Can't parse response into JSON", body
129
+ end
130
+
131
+ def json_post(url, payload)
132
+ http_post(url, payload.to_json, 'application/json')
133
+ end
134
+
135
+ def json_put(url, payload)
136
+ http_put(url, payload.to_json, 'application/json')
137
+ end
138
+
139
+ def json_parse(str)
140
+ if str
141
+ JSON.parse(str, :symbolize_names => true)
142
+ end
143
+ end
144
+
145
+ require 'rest_client'
146
+
147
+ # HTTP helpers
148
+
149
+ def http_get(path, content_type=nil)
150
+ request(:get, path, content_type)
151
+ end
152
+
153
+ def http_post(path, body, content_type=nil)
154
+ request(:post, path, content_type, body)
155
+ end
156
+
157
+ def http_put(path, body, content_type=nil)
158
+ request(:put, path, content_type, body)
159
+ end
160
+
161
+ def http_delete(path,content_type=nil)
162
+ request(:delete, path,content_type)
163
+ end
164
+
165
+ def request(method, path, content_type = nil, payload = nil, headers = {})
166
+ headers = headers.dup
167
+ headers['Authentication'] = @auth_token if @auth_token
168
+ if content_type
169
+ headers['Content-Type'] = content_type
170
+ headers['Accept'] = content_type
171
+ end
172
+ req = {
173
+ :method => method, :url => "#{@target}#{path}",
174
+ :payload => payload, :headers => headers
175
+ }
176
+ status, body, response_headers = perform_http_request(req)
177
+ if request_failed?(status)
178
+ err = (status == 404 || status == 400) ? NotFound : TargetError
179
+ raise err, parse_error_message(status, body)
180
+ else
181
+ return status, body, response_headers
182
+ end
183
+ rescue URI::Error, SocketError, Errno::ECONNREFUSED => e
184
+ raise BadTarget, "Cannot access target (%s)" % [ e.message ]
185
+ end
186
+
187
+ def request_failed?(status)
188
+ PI_HTTP_ERROR_CODES.detect{|error_code| status >= error_code}
189
+ end
190
+
191
+ def perform_http_request(req)
192
+ unless trace.nil?
193
+ req[:headers]['X-VCAP-Trace'] = (trace == true ? '22' : trace)
194
+ end
195
+
196
+ result = nil
197
+ RestClient::Request.execute(req) do |response, request|
198
+ result = [ response.code, response.body, response.headers ]
199
+ unless trace.nil?
200
+ puts '>>>'
201
+ puts "REQUEST: #{req[:method]} #{req[:url]}"
202
+ puts "RESPONSE_HEADERS:"
203
+ response.headers.each do |key, value|
204
+ puts " #{key} : #{value}"
205
+ end
206
+ puts "REQUEST_BODY: #{req[:payload]}" if req[:payload]
207
+ puts "RESPONSE: [#{response.code}]"
208
+ begin
209
+ puts JSON.pretty_generate(JSON.parse(response.body))
210
+ rescue
211
+ puts "#{response.body}"
212
+ end
213
+ puts '<<<'
214
+ end
215
+ end
216
+ result
217
+ rescue Net::HTTPBadResponse => e
218
+ raise BadTarget "Received bad HTTP response from target: #{e}"
219
+ rescue SystemCallError, RestClient::Exception => e
220
+ raise HTTPException, "HTTP exception: #{e.class}:#{e}"
221
+ end
222
+
223
+ def truncate(str, limit = 30)
224
+ etc = '...'
225
+ stripped = str.strip[0..limit]
226
+ if stripped.length > limit
227
+ stripped + etc
228
+ else
229
+ stripped
230
+ end
231
+ end
232
+
233
+ def parse_error_message(status, body)
234
+ parsed_body = json_parse(body.to_s)
235
+ if parsed_body && parsed_body[:code] && parsed_body[:description]
236
+ desc = parsed_body[:description].gsub("\"","'")
237
+ "Error #{parsed_body[:code]}: #{desc}"
238
+ else
239
+ "Error (HTTP #{status}): #{body}"
240
+ end
241
+ rescue JSON::ParserError
242
+ if body.nil? || body.empty?
243
+ "Error (#{status}): No Response Received"
244
+ else
245
+ body_out = trace ? body : truncate(body)
246
+ "Error (JSON #{status}): #{body_out}"
247
+ end
248
+ end
249
+
250
+ end
data/lib/pi/const.rb ADDED
@@ -0,0 +1,15 @@
1
+ module PI
2
+
3
+ VERSION = 'Bougatsa 0.6.0'
4
+
5
+ # Targets
6
+ DEFAULT_TARGET = 'https://api.staging.samsungcloud.org'
7
+ DEFAULT_LOCAL_TARGET = 'http://www.samsungcloud.org'
8
+
9
+ # General Paths
10
+ INFO_PATH = '/info'
11
+ TOKEN_PATH = '/token'
12
+ PROJECT_PATH = '/project'
13
+ USER_PATH = '/user'
14
+
15
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pi
3
+ version: !ruby/object:Gem::Version
4
+ hash: 1
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 13
10
+ version: 0.1.13
11
+ platform: ruby
12
+ authors:
13
+ - Samsung
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-07-09 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json_pure
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 1
29
+ segments:
30
+ - 1
31
+ - 5
32
+ - 1
33
+ version: 1.5.1
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: highline
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 13
45
+ segments:
46
+ - 1
47
+ - 6
48
+ - 1
49
+ version: 1.6.1
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: rest-client
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 13
61
+ segments:
62
+ - 1
63
+ - 6
64
+ - 1
65
+ version: 1.6.1
66
+ - - <
67
+ - !ruby/object:Gem::Version
68
+ hash: 11
69
+ segments:
70
+ - 1
71
+ - 7
72
+ - 0
73
+ version: 1.7.0
74
+ type: :runtime
75
+ version_requirements: *id003
76
+ - !ruby/object:Gem::Dependency
77
+ name: terminal-table
78
+ prerelease: false
79
+ requirement: &id004 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 1
87
+ - 4
88
+ - 2
89
+ version: 1.4.2
90
+ type: :runtime
91
+ version_requirements: *id004
92
+ - !ruby/object:Gem::Dependency
93
+ name: rake
94
+ prerelease: false
95
+ requirement: &id005 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ type: :development
105
+ version_requirements: *id005
106
+ - !ruby/object:Gem::Dependency
107
+ name: rspec
108
+ prerelease: false
109
+ requirement: &id006 !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ~>
113
+ - !ruby/object:Gem::Version
114
+ hash: 27
115
+ segments:
116
+ - 1
117
+ - 3
118
+ - 0
119
+ version: 1.3.0
120
+ type: :development
121
+ version_requirements: *id006
122
+ - !ruby/object:Gem::Dependency
123
+ name: webmock
124
+ prerelease: false
125
+ requirement: &id007 !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ~>
129
+ - !ruby/object:Gem::Version
130
+ hash: 3
131
+ segments:
132
+ - 1
133
+ - 5
134
+ - 0
135
+ version: 1.5.0
136
+ type: :development
137
+ version_requirements: *id007
138
+ description: Pi Command Line Tool
139
+ email: bstpaas@gmail.com
140
+ executables:
141
+ - pi
142
+ extensions: []
143
+
144
+ extra_rdoc_files:
145
+ - README
146
+ files:
147
+ - README
148
+ - Rakefile
149
+ - lib/cli/config.rb
150
+ - lib/cli/version.rb
151
+ - lib/cli/errors.rb
152
+ - lib/cli/core_ext.rb
153
+ - lib/cli/commands/misc.rb
154
+ - lib/cli/commands/base.rb
155
+ - lib/cli/commands/user.rb
156
+ - lib/cli/commands/projects.rb
157
+ - lib/cli/runner.rb
158
+ - lib/cli/usage.rb
159
+ - lib/pi.rb
160
+ - lib/pi/const.rb
161
+ - lib/pi/client.rb
162
+ - lib/cli.rb
163
+ - bin/pi
164
+ homepage: http://www.samsungcloud.org/
165
+ licenses: []
166
+
167
+ post_install_message:
168
+ rdoc_options: []
169
+
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ none: false
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ hash: 3
178
+ segments:
179
+ - 0
180
+ version: "0"
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ none: false
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ hash: 3
187
+ segments:
188
+ - 0
189
+ version: "0"
190
+ requirements: []
191
+
192
+ rubyforge_project:
193
+ rubygems_version: 1.8.15
194
+ signing_key:
195
+ specification_version: 3
196
+ summary: Commandline tool that provides access to Samsung Cloud Platform.
197
+ test_files: []
198
+