cc-terminal 0.0.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.ruby-version +1 -0
  4. data/.yardopts +3 -0
  5. data/Gemfile +15 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +33 -0
  8. data/Rakefile +1 -0
  9. data/lib/terminal.rb +13 -0
  10. data/lib/terminal/api.rb +15 -0
  11. data/lib/terminal/client.rb +55 -0
  12. data/lib/terminal/errors.rb +22 -0
  13. data/lib/terminal/modules/browse_snapshots_and_users.rb +67 -0
  14. data/lib/terminal/modules/create_and_manage_snapshots.rb +90 -0
  15. data/lib/terminal/modules/create_and_manage_terminals.rb +125 -0
  16. data/lib/terminal/modules/request_progress.rb +20 -0
  17. data/lib/terminal/request.rb +16 -0
  18. data/lib/terminal/request/encode_json.rb +52 -0
  19. data/lib/terminal/response/parse_json.rb +31 -0
  20. data/lib/terminal/response/raise_error_from_json.rb +23 -0
  21. data/lib/terminal/utils.rb +11 -0
  22. data/lib/terminal/version.rb +3 -0
  23. data/spec/fixtures/count_public_snapshots.json +1 -0
  24. data/spec/fixtures/count_snapshots.json +1 -0
  25. data/spec/fixtures/delete_snapshot.json +1 -0
  26. data/spec/fixtures/edit_snapshot.json +1 -0
  27. data/spec/fixtures/error_response.json +1 -0
  28. data/spec/fixtures/get_profile.json +1 -0
  29. data/spec/fixtures/get_snapshot.json +1 -0
  30. data/spec/fixtures/list_public_snapshots.json +1 -0
  31. data/spec/fixtures/list_snapshots.json +1 -0
  32. data/spec/fixtures/list_terminals.json +1 -0
  33. data/spec/fixtures/request_progress.json +1 -0
  34. data/spec/helper.rb +22 -0
  35. data/spec/terminal/client_spec.rb +41 -0
  36. data/spec/terminal/modules/browse_snapshots_and_users_spec.rb +24 -0
  37. data/spec/terminal/modules/create_and_manage_snapshots_spec.rb +27 -0
  38. data/spec/terminal/modules/create_and_manage_terminals_spec.rb +25 -0
  39. data/spec/terminal/modules/request_progress_spec.rb +25 -0
  40. data/terminal.gemspec +25 -0
  41. metadata +129 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 427b3afc83f5bc223e98b076bf0d6c8fb08c7b37
4
+ data.tar.gz: aecf2ed8c990a4ae92e9447d90170cf8641d7f5f
5
+ SHA512:
6
+ metadata.gz: 3740f125d965595ebb8e2a6c0e53081087f42d7fac7e99dafe6e769b1e0d87c21f14a73694b1dd38745b74faf9b54cd281d2ede1978ef5862f27c941568a049f
7
+ data.tar.gz: a797f43497f81b05557e8d739dbae4e1d54abbfeb166295fc18dba60ae22a868b0f15f5641eaac4342b7218f33a5afe5a7ca2b0f2e136cccbb051cd47509e7b1
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
@@ -0,0 +1 @@
1
+ 2.0.0-p353
@@ -0,0 +1,3 @@
1
+ --tag authentication:"Authentication"
2
+ --tag required_option:"Required Option"
3
+ --markup markdown
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'yard'
5
+ group :development do
6
+ gem 'pry'
7
+ end
8
+
9
+ group :test do
10
+ gem 'webmock'
11
+ gem 'rspec', '>= 2.14'
12
+ gem 'simplecov', :require => false
13
+ gem "codeclimate-test-reporter", require: nil
14
+ end
15
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Timor Tsentsiper
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.
@@ -0,0 +1,33 @@
1
+ # Terminal
2
+
3
+ TODO: Write a gem description
4
+
5
+ <a href="https://codeclimate.com/repos/53fce1de69568062c701f989/feed"><img src="https://codeclimate.com/repos/53fce1de69568062c701f989/badges/15eedb01e45d861429ca/gpa.svg" /></a>
6
+ [![CircleCI](https://circleci.com/gh/RyzacInc/terminal/tree/master.svg?style=shield&circle-token=3c6941fc03c8252853e6f6a8922927bab1513f90)](https://circleci.com/gh/RyzacInc/terminal)
7
+
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'terminal'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install terminal
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,13 @@
1
+ require "terminal/version"
2
+ require "terminal/errors"
3
+ require "terminal/request/encode_json"
4
+ require "terminal/response/parse_json"
5
+ require "terminal/response/raise_error_from_json"
6
+ require "terminal/modules/create_and_manage_terminals"
7
+ require "terminal/modules/create_and_manage_snapshots"
8
+ require "terminal/modules/request_progress"
9
+ require "terminal/modules/browse_snapshots_and_users"
10
+ require "terminal/api"
11
+ require "terminal/request"
12
+ require "terminal/utils"
13
+ require "terminal/client"
@@ -0,0 +1,15 @@
1
+ module Terminal
2
+ module API
3
+ include Terminal::Modules::BrowseSnapshotsAndUsers
4
+ include Terminal::Modules::CreateAndManageTerminals
5
+ include Terminal::Modules::CreateAndManageSnapshots
6
+ include Terminal::Modules::RequestProgress
7
+ # include Terminal::Modules::CreateSnapshots
8
+ # include Terminal::Modules::ManageSnapshots
9
+ # include Terminal::Modules::BrowseSnapshots
10
+ # include Terminal::Modules::ManageUsers
11
+ # include Terminal::Modules::BrowseUsers
12
+ # include Terminal::Modules::ManageUsageAndCredits
13
+ end
14
+ end
15
+
@@ -0,0 +1,55 @@
1
+
2
+ module Terminal
3
+ class Client
4
+ include Terminal::API
5
+
6
+ API_VERSION = "v0.1"
7
+ API_URL = 'https://api.terminal.com'
8
+ API_PREFIX = API_URL + "/" + API_VERSION + "/"
9
+
10
+ attr_accessor :user_token, :access_token
11
+
12
+ def initialize( options = {})
13
+ options.each do | k, v |
14
+ if v.is_a?(Integer)
15
+ raise Terminal::APIConfigurationError
16
+ end
17
+ send(:"#{k}=", v)
18
+ end
19
+ yield(self) if block_given?
20
+ end
21
+
22
+ def post(path, params = {} )
23
+ request(:post, path, params)
24
+ end
25
+
26
+ private
27
+
28
+ def connection(options = {} )
29
+ @connection ||= Faraday.new(API_URL, options) do | conn |
30
+ conn.request :encode_json
31
+ conn.adapter :net_http
32
+ conn.response :parse_json
33
+ conn.response :raise_error_from_json
34
+ end
35
+ end
36
+
37
+ def request(method, path, params = {})
38
+ auth = params.delete(:auth)
39
+ params = params.merge(auth_params) if auth
40
+ connection.send(method.to_sym, API_PREFIX + path, params)
41
+ rescue Faraday::Error::TimeoutError, Timeout::Error => error
42
+ raise(Terminal::APITimeoutError.new(error))
43
+ end
44
+
45
+ def auth_params
46
+ params = {}
47
+ params[:access_token] = access_token
48
+ params[:user_token] = user_token
49
+ params
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+
@@ -0,0 +1,22 @@
1
+ module Terminal
2
+ class APITimeoutError < StandardError; end
3
+ class APIConfigurationError < StandardError; end
4
+
5
+ class APIResponseError < StandardError
6
+
7
+ attr_reader :message, :status
8
+ def initialize(body)
9
+ @message, @status = parse_error_body(body)
10
+ super(message)
11
+ end
12
+
13
+ private
14
+ def parse_error_body(body)
15
+ if body.nil?
16
+ ['', nil]
17
+ elsif body[:error]
18
+ [body[:error], body[:success]]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,67 @@
1
+ require 'terminal/utils'
2
+
3
+ module Terminal
4
+ module Modules
5
+ module BrowseSnapshotsAndUsers
6
+
7
+ include Terminal::Utils
8
+
9
+ # Get information about a snapshot
10
+ #
11
+ # @see https:://www.terminal.com/api/docs#get-snapshot
12
+ # @authentication No auth required
13
+ # @param snapshot_id [String] the id of the snapshot you want info about
14
+ # @return [Hash] snapshot information, top level :snapshot [:title, :body, :readme, :tags ...] etc
15
+ def get_snapshot(snapshot_id)
16
+ perform(:post, 'get_snapshot', { :snapshot_id => snapshot_id })
17
+ end
18
+
19
+ # Get information about a user
20
+ #
21
+ # @see https:://www.terminal.com/api/docs#get-profile
22
+ # @authentication No auth required
23
+ # @param username [String] The user to look up
24
+ # @return [Hash] user information, top level :user [:name, :username, :url ...] etc
25
+ def get_profile(username)
26
+ perform(:post, 'get_profile', { :username => username })
27
+ end
28
+
29
+ # List public snapshots, optionally filtered by the owner's
30
+ # username, a tag, or the snapshot's featured status. Combinations of filters
31
+ # are fine.
32
+ #
33
+ # @see https://www.terminal.com/api/docs#list-public-snapshots
34
+ # @authentication No auth required
35
+ # @param username [String]
36
+ # @param options [Hash]
37
+ # @option options tag [String] tag the snapshot was created with
38
+ # @option options featured [Boolean] true/false
39
+ # @option options title [String] title of the snapshot
40
+ # @option options page [Integer] 0
41
+ # @option options perPage [Integer] results per page 10
42
+ # @option options sortby [String] popularity, date etc
43
+ # @return [Hash] hash of snapshots, top level key :snapshots
44
+ def list_public_snapshots(username, options = {})
45
+ options[:username] = username
46
+ perform(:post, 'list_public_snapshots', options)
47
+ end
48
+
49
+ # Get count of public snapshots, optionally filtered by the owner's
50
+ # username, a tag, or the snapshot's featured status. Combinations of filters
51
+ # are fine.
52
+ #
53
+ # @see https://www.terminal.com/api/docs#count-public-snapshots
54
+ # @authentication No auth required
55
+ # @param username [String]
56
+ # @param options [Hash]
57
+ # @option options tag [String] tag the snapshot was created with
58
+ # @option options featured [Boolean] true/false
59
+ # @option options title [String] title of the snapshot
60
+ # @return [Hash] has of 1 key the count, :snapshot_count
61
+ def count_public_snapshots(username, options = {})
62
+ options[:username] = username
63
+ perform(:post, 'count_public_snapshots', options)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,90 @@
1
+ require 'terminal/utils'
2
+
3
+ module Terminal
4
+ module Modules
5
+ module CreateAndManageSnapshots
6
+
7
+ include Terminal::Utils
8
+
9
+
10
+ # Returns a list of all your snapshots, filtered by options
11
+ #
12
+ # @see https://www.terminal.com/api/docs#list-snapshots
13
+ # @authentication Requires user_token and access_token
14
+ # @param options [Hash] options to filter results on
15
+ # @option options username [String] filter by the username
16
+ # @option options tag [String] filter by the tag
17
+ # @option options featured [Boolean] is it featured
18
+ # @option options title [String] the title of the snapshot
19
+ # @option options page [Integer] WTF
20
+ # @option options perPage [Integer] paginate results I think
21
+ # @option options sortby [String] popularity or date
22
+ # @return [Hash] of snapshots, the key :snapshots is top level
23
+ def list_snapshots(options = {})
24
+ options[:auth] = true
25
+ perform(:post, 'list_snapshots', options)
26
+ end
27
+
28
+ # Returns a count of all your snapshots, filtered by options
29
+ #
30
+ # @see https://www.terminal.com/api/docs#count-snapshots
31
+ # @authentication Requires user_token and access_token
32
+ # @param options [Hash] options to filter on
33
+ # @option options username [String] filter by the owner's username
34
+ # @option options tag [String] filter by a tag
35
+ # @option options featured [Boolean] filter by featured status
36
+ # @option options title [String] filter by the title of the snapshot
37
+ # @return [Hash] count, the key :snapshots_count is top level
38
+ def count_snapshots(options = {})
39
+ options[:auth] = true
40
+ perform(:post, 'count_snapshots', options)
41
+ end
42
+
43
+ # Delete a snapshot by id
44
+ #
45
+ # @see https://www.terminal.com/api/docs#delete-snapshot
46
+ # @authentication Requires user_token and access_token
47
+ # @param snapshot_id [String] the id of the snapshot to delete
48
+ # @return [Hash]
49
+ def delete_snapshot(snapshot_id)
50
+ options = {}
51
+ options[:auth] = true
52
+ options[:snapshot_id] = snapshot_id
53
+ perform(:post, 'delete_snapshot', options)
54
+ end
55
+
56
+ # Edit the metadata of a snapshot owned by your account.
57
+ #
58
+ # @see https://www.terminal.com/api/docs#edit-snapshot
59
+ # @authentication Require user_token and access token
60
+ # @param snapshot_id [String] the id of the snapshot you want to edit
61
+ # @param options [Hash] options you want to edit (snapshot meta data)
62
+ # @option options body [String]
63
+ # @option options title [String]
64
+ # @option options readme [String]
65
+ # @option options tags [Array]
66
+ # @option options public [Boolean]
67
+ def edit_snapshot(snapshot_id, options ={})
68
+ options[:auth] = true
69
+ options[:snapshot_id] = snapshot_id
70
+ perform(:post, 'edit_snapshot', options)
71
+ end
72
+
73
+ # Create a snapshot of a terminal instance, but it actually makes no sense
74
+ #
75
+ # @see https://www.terminal.com/api/docs#snapshot-terminal
76
+ # @authentication Requires user_token and access_token
77
+ # @param container_key [String]
78
+ # @param snapshot_id [String]
79
+ # @param options [Hash]
80
+ # @option options body
81
+ # @return [Hash]
82
+ def snapshot_terminal(container_key, snapshot_id, options = {})
83
+ options[:auth] = true
84
+ options[:container_key] = container_key
85
+ options[:snapshot_id] = snapshot_id
86
+ perform(:post, 'snapshot_terminal', options)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,125 @@
1
+ require 'terminal/utils'
2
+
3
+ module Terminal
4
+ module Modules
5
+ module CreateAndManageTerminals
6
+
7
+ include Terminal::Utils
8
+
9
+ # Returns a list of all your terminals
10
+ #
11
+ # @see https://www.terminal.com/api/docs#list-terminals
12
+ # @authentication Requires user_token and access_token
13
+ # @return [Hash] of terminals, the key :terminals is top level
14
+ def list_terminals
15
+ options = {}
16
+ options[:auth] = true
17
+ perform(:post, 'list_terminals', options )
18
+ end
19
+
20
+ # Returns info about a specific terminal
21
+ #
22
+ # @see https://www.terminal.com/api/docs#get-terminal
23
+ # @authentication Requires user_token and access_token
24
+ # @param container_key [String] the id/key of the container and is optional
25
+ # @param subdomain [String] the sub domain of the terminal and is optional
26
+ # @return [Hash] represents one terminal, the hash is its attributes
27
+ def get_terminal(container_key = nil, subdomain = nil)
28
+ options = {}
29
+ options[:auth] = true
30
+ options[:container_key] = container_key unless container_key.nil?
31
+ options[:subdomain] = subdomain unless subdomain.nil?
32
+ perform(:post, 'get_terminal', options)
33
+ end
34
+
35
+ # Start a terminal instance based on a snapshot
36
+ #
37
+ # @see https://www.terminal.com/api/docs#start-snapshot
38
+ # @authentication Requires user_token and access_token
39
+ # @param snapshot_id [String] the id of the snapshot you are trying to start
40
+ # @param options [Hash] options to add to the request
41
+ # @option options cpu [String] Example: "2 (max)" unclear if this is even honored by Terminal.com api
42
+ # @option options ram [String]
43
+ # @option options temporary [Boolean]
44
+ # @option options name [String]
45
+ # @option options autopause [Boolean]
46
+ # @option options startup_script [String]
47
+ # @return [Hash] represents the request_id you just made (to check its status is another call)
48
+ def start_snapshot(snapshot_id, options = {})
49
+ options[:auth] = true
50
+ options[:snapshot_id] = snapshot_id
51
+ perform(:post, 'start_snapshot', options)
52
+ end
53
+
54
+ # Delete a terminal instance
55
+ #
56
+ # @see https://www.terminal.com/api/docs#delete-terminal
57
+ # @authentication Requires user_token and access_token
58
+ # @param container_key [String] the key of the terminal you are trying to delete
59
+ # @return [Hash] represents the :status of the request and the :result
60
+ def delete_terminal(container_key)
61
+ options = {}
62
+ options[:auth] = true
63
+ options[:container_key] = container_key
64
+ perform(:post, 'delete_terminal', options)
65
+ end
66
+
67
+ # Restart a terminal instance
68
+ #
69
+ # @see https://www.terminal.com/api/docs#restart-terminal
70
+ # @authentication Requires user_token and access_token
71
+ # @param container_key [String] the key of the terminal you are trying to restart
72
+ # @return [Hash] represents the request_id that was made on the API
73
+ def restart_terminal(container_key)
74
+ options = {}
75
+ options[:auth] = true
76
+ options[:container_key] = container_key
77
+ perform(:post, 'restart_terminal', options)
78
+ end
79
+
80
+ # Pause a terminal instance
81
+ #
82
+ # @see https://www.terminal.com/api/docs#pause-terminal
83
+ # @authentication Requires user_token and access_token
84
+ # @param container_key [String] the key of the terminal you are trying to pause
85
+ # @return [Hash] represents the request_id that was made on the API
86
+ def pause_terminal(container_key)
87
+ options = {}
88
+ options[:auth] = true
89
+ options[:container_key] = container_key
90
+ perform(:post, 'pause_terminal', options)
91
+ end
92
+
93
+ # Resume a terminal instance
94
+ #
95
+ # @see https://www.terminal.com/api/docs#resume-terminal
96
+ # @authentication Requires user_token and access_token
97
+ # @param container_key [String] the key of the terminal you are trying to resume
98
+ # @return [Hash] represents the request_id that was made on the API
99
+ def resume_terminal(container_key)
100
+ options = {}
101
+ options[:auth] = true
102
+ options[:container_key] = container_key
103
+ perform(:post, 'resume_terminal', options)
104
+ end
105
+
106
+ # Edit the resources and/or name of a Terminal instance
107
+ #
108
+ # @see https://www.terminal.com/api/docs#edit-terminal
109
+ # @authentication Requires user_token and access_token
110
+ # @param container_key [String] the id of the terminal you are trying to edit
111
+ # @param required_options [Hash] hash of other required params cpu, ram, diskspace, name
112
+ # @required_option cpu [String] cpu of the terminal to edit to
113
+ # @required_option ram [String] ram to edit the terminal to
114
+ # @required_option cpu [String] disk space to edit to
115
+ # @required_option name [String] name to edit the terminal to
116
+ # @return [Hash] Hash containing the :status and the :request_id for the request
117
+ def edit_terminal(container_key, required_options ={})
118
+ required_options[:auth] = true
119
+ requireed_options[:container_key] = container_key
120
+ perform(:post, 'edit_terminal', required_options)
121
+ end
122
+
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,20 @@
1
+ require 'terminal/utils'
2
+
3
+ module Terminal
4
+ module Modules
5
+ module RequestProgress
6
+ include Terminal::Utils
7
+
8
+ # Get info and status of an API request
9
+ #
10
+ # @see https://www.terminal.com/api/docs#request-progress
11
+ # @param request_id [String] the request id you are trying to get more info about
12
+ # @return [Hash] of terminals, the key :terminals is top level
13
+ def request_progress(request_id)
14
+ options = {}
15
+ options[:request_id] = request_id
16
+ perform(:post, 'request_progress', options )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module Terminal
2
+ class Request
3
+ attr_accessor :client, :request_method, :path, :options
4
+
5
+ def initialize(client, request_method, path, options = {})
6
+ @client = client
7
+ @request_method = request_method
8
+ @path = path
9
+ @options = options
10
+ end
11
+
12
+ def perform
13
+ @client.send(@request_method, @path, @options).body
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,52 @@
1
+ # From https://github.com/lostisland/faraday_middleware/blob/master/lib/faraday_middleware/request/encode_json.rb
2
+ require 'faraday'
3
+ require 'json'
4
+
5
+ module Terminal
6
+ module RequestExt
7
+ class EncodeJson < Faraday::Middleware
8
+ CONTENT_TYPE = 'Content-Type'.freeze
9
+ MIME_TYPE = 'application/json'.freeze
10
+
11
+ dependency do
12
+ require 'json' unless defined?(::JSON)
13
+ end
14
+
15
+ def call(env)
16
+ match_content_type(env) do |data|
17
+ env[:body] = encode data
18
+ end
19
+ @app.call env
20
+ end
21
+
22
+ def encode(data)
23
+ ::JSON.dump data
24
+ end
25
+
26
+ def match_content_type(env)
27
+ if process_request?(env)
28
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
29
+ yield env[:body] unless env[:body].respond_to?(:to_str)
30
+ end
31
+ end
32
+
33
+ def process_request?(env)
34
+ type = request_type(env)
35
+ has_body?(env) and (type.empty? or type == MIME_TYPE)
36
+ end
37
+
38
+ def has_body?(env)
39
+ body = env[:body] and !(body.respond_to?(:to_str) and body.empty?)
40
+ end
41
+
42
+ def request_type(env)
43
+ type = env[:request_headers][CONTENT_TYPE].to_s
44
+ type = type.split(';', 2).first if type.index(';')
45
+ type
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+
52
+ Faraday::Request.register_middleware :encode_json => Terminal::RequestExt::EncodeJson
@@ -0,0 +1,31 @@
1
+ # From https://github.com/sferik/twitter/blob/master/lib/twitter/rest/response/parse_json.rb
2
+ require 'faraday'
3
+ require 'json'
4
+
5
+
6
+ module Terminal
7
+ module ResponseExt
8
+ class ParseJson < Faraday::Response::Middleware
9
+ WHITESPACE_REGEX = /\A^\s*$\z/
10
+
11
+ def parse(body)
12
+ case body
13
+ when WHITESPACE_REGEX, nil
14
+ nil
15
+ else
16
+ JSON.parse(body, :symbolize_names => true)
17
+ end
18
+ end
19
+
20
+ def on_complete(response)
21
+ response.body = parse(response.body) if respond_to?(:parse) && !unparsable_status_codes.include?(response.status)
22
+ end
23
+
24
+ def unparsable_status_codes
25
+ [204, 301, 302, 304]
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ Faraday::Response.register_middleware :parse_json => Terminal::ResponseExt::ParseJson
@@ -0,0 +1,23 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+
5
+ module Terminal
6
+ module ResponseExt
7
+ class RaiseErrorFromJson < Faraday::Response::Middleware
8
+ def on_complete(response)
9
+ # Terminal.com always returns 200
10
+ code = response.status.to_i
11
+ body = JSON.parse(response.body, :symbolize_names => true)
12
+ if code == 200 && body[:success] == false || !body[:error].nil?
13
+ fail(Terminal::APIResponseError.new(body))
14
+ else
15
+ # How did we get here?
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+
23
+ Faraday::Response.register_middleware :raise_error_from_json => Terminal::ResponseExt::RaiseErrorFromJson
@@ -0,0 +1,11 @@
1
+ module Terminal
2
+ module Utils
3
+
4
+ private
5
+
6
+ def perform(request_method, path, options)
7
+ request = Terminal::Request.new(self, request_method, path, options)
8
+ request.perform
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Terminal
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1 @@
1
+ {"snapshot_count":19}
@@ -0,0 +1 @@
1
+ {"snapshot_count":2}
@@ -0,0 +1 @@
1
+ {"status":"success"}
@@ -0,0 +1 @@
1
+ {:snapshot=>{:title=>"Timor Test", :body=>"Box With Authorized Keys", :display_style=>"readme", :readme=>"", :pynb=>"", :tags=>"", :image=>{:files=>["1406148593621.png"], :cdnUri=>"http://s3-us-west-2.amazonaws.com/com.terminal.imager"}, :diskspace=>10, :ram=>256, :public=>false, :start_count=>0, :createdAt=>"2014-09-03T16:19:28.672Z", :featured=>false, :author=>"codecademy", :id=>"4d9047f516b4c4861db55b52c9130393fb188e97e7f7831551090def8a8f90e8"}, :success=>true}
@@ -0,0 +1 @@
1
+ {"error":"No such user"}
@@ -0,0 +1 @@
1
+ {"user":{"name":"varun","username":"varunc","url":"http://www.stanford.edu/~varung","company":"Terminal.com","location":"San Francisco, CA","profile_image":"//www.gravatar.com/avatar/e06ae167720f9383b8b34aa0a5fddd8d.jpg?s=400&d=mm"}}
@@ -0,0 +1 @@
1
+ {"snapshot":{"title":"Official Centos 6","body":"Official Centos 6 distribution with minimal stack for running Terminal.com IDE. Install anything, you have root access.","display_style":"readme","readme":"","pynb":"","tags":"centos","image":{"files":["1406144007836.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":true,"start_count":3153,"createdAt":"2014-07-23T19:32:31.207Z","comments":[],"featured":true,"author":"terminal","id":"2dca905d923d8154c555c5271cbba75927cb3fd705aba1eb9d93cbd59e3ef100"}}
@@ -0,0 +1 @@
1
+ {"snapshots":[{"title":"Official Centos 6","body":"Official Centos 6 distribution with minimal stack for running Terminal.com IDE. Install anything, you have root access.","display_style":"readme","readme":"","pynb":"","tags":"centos","image":{"files":["1406144007836.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":true,"start_count":2261,"createdAt":"2014-08-01T15:52:53.392Z","featured":false,"author":"terminal","id":"7055b7ad84fa386fd023cf9bdb91434a09c97daede1624705777aa9b4758e44b"},{"title":"Official Scientific Linux 6","body":"Official Scientific Linux 6 distribution with minimal stack for running Terminal.com IDE. Install anything, you have root access.","display_style":"readme","readme":"","pynb":"","tags":"scientific-linux","image":{"files":["1406152673695.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":true,"start_count":1016,"createdAt":"2014-07-23T21:56:13.810Z","featured":true,"author":"terminal","id":"ee99eb373155dd321e65664e0987d5a5ac7de71a63c62117a33f9c1b7074bbbf"},{"title":"Official Ubuntu 14.04","body":"Official Ubuntu 14.04 distribution with minimal stack for running Terminal.com IDE. Install anything, you have root access.","display_style":"readme","readme":"","pynb":"","tags":"ubuntu","image":{"files":["1406148593621.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":true,"start_count":3153,"createdAt":"2014-07-23T20:27:41.743Z","featured":true,"author":"terminal","id":"987f8d702dc0a6e8158b48ccd3dec24f819a7ccb2756c396ef1fd7f5b34b7980"},{"title":"Official Centos 6","body":"Official Centos 6 distribution with minimal stack for running Terminal.com IDE. Install anything, you have root access.","display_style":"readme","readme":"","pynb":"","tags":"centos","image":{"files":["1406144007836.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":true,"start_count":3153,"createdAt":"2014-07-23T19:32:31.207Z","featured":true,"author":"terminal","id":"2dca905d923d8154c555c5271cbba75927cb3fd705aba1eb9d93cbd59e3ef100"},{"title":"Official Debian 7.0","body":"Official Debian 7.0 distribution with minimal stack for running Terminal.com IDE. Install anything, you have root access.","display_style":"readme","readme":"","pynb":"","tags":"debian","image":{"files":["1406143176054.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":true,"start_count":2230,"createdAt":"2014-07-23T19:16:57.738Z","featured":true,"author":"terminal","id":"4bd31cfeb39ab2fdb8a84f0e4e6061f0ad0d718299198a3339c56bf32eda93fd"}]}
@@ -0,0 +1 @@
1
+ {"snapshots":[{"title":"Base","body":"Box With Authorized Keys","display_style":"readme","readme":"","pynb":"","tags":"","image":{"files":["1406148593621.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":false,"start_count":0,"createdAt":"2014-08-20T14:51:00.894Z","featured":false,"author":"codecademy","id":"a2e2e283b3e50e61530b49487716ce668154cbb33fb18317078d976a87a54f92"},{"title":"Box With Keys","body":"Box With Authorized Keys","display_style":"readme","readme":"","pynb":"","tags":"","image":{"files":["1406148593621.png"],"cdnUri":"http://s3-us-west-2.amazonaws.com/com.terminal.imager"},"diskspace":10,"ram":256,"public":false,"start_count":1,"createdAt":"2014-08-18T21:12:37.987Z","featured":false,"author":"codecademy2","id":"88c27f6f1bb367e8fa0163e1dc22eec438a6d164ab8204e5827d2b5815f11945"}]}
@@ -0,0 +1 @@
1
+ {"terminals":[{"cpu":"2 (max)","ram":"256","diskspace":"10","name":"Base","snapshot_id":"987f8d702dc0a6e8158b48ccd3dec24f819a7ccb2756c396ef1fd7f5b34b7980","temporary":"","status":"running","allow_spot":false,"container_key":"ade4d0fe-a98a-48e8-a087-6b7c8fe9c164","hostname":"codecademy2","subdomain":"codecademy2","container_ip":"192.0.65.8","creation_time":1408395945876},{"cpu":"2 (max)","ram":"256m","diskspace":"10","name":"Dan's Provisioning Box","snapshot_id":"88c27f6f1bb367e8fa0163e1dc22eec438a6d164ab8204e5827d2b5815f11945","temporary":"","status":"running","allow_spot":false,"container_key":"4c68a7c5-75a7-4a7b-a58f-3815f10258b1","hostname":"codecademy3","subdomain":"codecademy3","container_ip":"192.0.65.17","creation_time":1408399878526}]}
@@ -0,0 +1 @@
1
+ {"status":"success","result":{"cpu":"2 (max)","ram":256,"diskspace":10,"name":"Box With Keys","snapshot_id":"88c27f6f1bb367e8fa0163e1dc22eec438a6d164ab8204e5827d2b5815f11945","status":"running","allow_spot":false,"container_key":"64cb36a5-8393-433a-ad16-e6053b5509ea","subdomain":"codecademy8","container_ip":"192.0.75.196","creation_time":1409693130184},"operation":"create","state":"success"}
@@ -0,0 +1,22 @@
1
+ require 'terminal'
2
+ require 'webmock/rspec'
3
+
4
+ if ENV['CIRCLE_ARTIFACTS']
5
+ require 'simplecov'
6
+ dir = File.join("..", "..", "..", ENV['CIRCLE_ARTIFACTS'], "coverage")
7
+ SimpleCov.coverage_dir(dir)
8
+ end
9
+
10
+ def a_post(path)
11
+ a_request(:post, Terminal::Client::API_PREFIX + path)
12
+ end
13
+
14
+ def stub_post(path)
15
+ stub_request(:post, Terminal::Client::API_PREFIX + path)
16
+ end
17
+
18
+ def fixture(file)
19
+ f_path = File.expand_path('../fixtures', __FILE__)
20
+ File.new(f_path + '/' + file)
21
+ end
22
+
@@ -0,0 +1,41 @@
1
+ require 'helper'
2
+
3
+ describe Terminal::Client do
4
+ before do
5
+ @client = Terminal::Client.new(:access_token => 'blah', :user_token => 'blah2')
6
+ end
7
+
8
+ describe 'new instance of the client is defined' do
9
+
10
+ context 'when bad access_token,user_token are provided' do
11
+ it 'raises a configuration exception' do
12
+ expect { Terminal::Client.new(:access_token => 12121, :user_token => 12111111) }.to raise_exception(Terminal::APIConfigurationError)
13
+ end
14
+ end
15
+ context 'when no access_token,user_token are provided' do
16
+ it 'does not raise an exception' do
17
+ expect { Terminal::Client.new }.not_to raise_error
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'connection' do
23
+ it 'looks like a Faraday connection' do
24
+ expect(@client.send(:connection)).to respond_to(:run_request)
25
+ end
26
+ end
27
+
28
+ describe 'request' do
29
+ it 'catches Faraday Timeout errors and raises an API timeout error' do
30
+ allow(@client).to receive(:connection).and_raise(Faraday::Error::TimeoutError.new('expired'))
31
+ expect { @client.send(:request, :post, '/blah') }.to raise_error(Terminal::APITimeoutError)
32
+ end
33
+
34
+ it 'raises an API error from a response containing error JSON' do
35
+ stub_post('/path').to_return(:body => fixture('error_response.json'), :headers => {:content_type => 'application/json'})
36
+ expect { @client.send(:request, :post, '/path')}.to raise_error(Terminal::APIResponseError)
37
+ end
38
+ end
39
+
40
+ end
41
+
@@ -0,0 +1,24 @@
1
+ require 'helper'
2
+
3
+ describe Terminal::Modules::BrowseSnapshotsAndUsers do
4
+ before do
5
+ @client = Terminal::Client.new(:access_token => 'blah', :user_token => 'blah2')
6
+ end
7
+
8
+ describe "get_snapshot" do
9
+ before do
10
+ stub_post('get_snapshot').to_return(:body => fixture('get_snapshot.json'), :headers => {:content_type => 'application/json'})
11
+ end
12
+
13
+ it 'calls the proper endpoint' do
14
+ @client.get_snapshot('some_id')
15
+ expect(a_post('get_snapshot')).to have_been_made
16
+ end
17
+
18
+ it 'returns a hash with some snapshot information' do
19
+ snapshot = @client.get_snapshot('some_id')
20
+ expect(snapshot[:snapshot]).to be_an(Hash)
21
+ expect(snapshot[:snapshot][:id]).to be_an(String)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ require 'helper'
2
+
3
+ describe Terminal::Modules::CreateAndManageSnapshots do
4
+ before do
5
+ @client = Terminal::Client.new(:access_token => 'blah', :user_token => 'blah2')
6
+ end
7
+
8
+ describe "get a list of snapshots" do
9
+ before do
10
+ stub_post('list_snapshots').to_return(:body => fixture('list_snapshots.json'), :headers => {:content_type => 'application/json'})
11
+ end
12
+
13
+ it 'posts to the proper endpoint' do
14
+ @client.list_snapshots
15
+ expect(a_post('list_snapshots')).to have_been_made
16
+ end
17
+
18
+ it 'contains a response that has some snapshots' do
19
+ snapshots = @client.list_snapshots
20
+ expect(snapshots).to be_an Hash
21
+ expect(snapshots[:snapshots]).to be_an Array
22
+ snapshot = snapshots[:snapshots].first
23
+ expect(snapshot).to be_an Hash
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ require 'helper'
2
+
3
+ describe Terminal::Modules::CreateAndManageTerminals do
4
+ before do
5
+ @client = Terminal::Client.new(:access_token => 'blah', :user_token => 'blah2')
6
+ end
7
+
8
+ describe "get a list of terminals" do
9
+ before do
10
+ stub_post('list_terminals').to_return(:body => fixture('list_terminals.json'), :headers => {:content_type => 'application/json'})
11
+ end
12
+
13
+ it 'posts to the proper endpoint' do
14
+ @client.list_terminals
15
+ expect(a_post('list_terminals')).to have_been_made
16
+ end
17
+
18
+ it 'contains a response that has some terminals' do
19
+ terminals = @client.list_terminals
20
+ expect(terminals).to be_an Hash
21
+ expect(terminals[:terminals]).to be_an Array
22
+ # Maybe check the actual structure here as well
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'helper'
2
+
3
+ describe Terminal::Modules::RequestProgress do
4
+ before do
5
+ @client = Terminal::Client.new(:access_token => 'blah', :user_token => 'blah2')
6
+ end
7
+
8
+ describe "Request progress endpoint called" do
9
+ before do
10
+ stub_post('request_progress').to_return(:body => fixture('request_progress.json'), :headers => {:content_type => 'application/json'})
11
+ end
12
+
13
+ it 'posts to the proper endpoint' do
14
+ @client.request_progress(:request_id => "testestest")
15
+ expect(a_post('request_progress')).to have_been_made
16
+ end
17
+
18
+ it 'returns a hash that is properly formed' do
19
+ request_status = @client.request_progress(:request_id => 'test')
20
+ expect(request_status).to be_an(Hash)
21
+ expect(request_status[:status]).to be_truthy
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'terminal/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cc-terminal"
8
+ spec.version = Terminal::VERSION
9
+ spec.authors = ["Timor Tsentsiper"]
10
+ spec.email = ["timor@codecademy.com"]
11
+ spec.description = %q{Write a gem description}
12
+ spec.summary = %q{Write a gem summary}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'json', '~> 1.8'
22
+ spec.add_dependency "faraday", '~> 0.9.0'
23
+ spec.required_ruby_version = '>= 2.0'
24
+ end
25
+
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cc-terminal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Timor Tsentsiper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
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
+ description: Write a gem description
42
+ email:
43
+ - timor@codecademy.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .ruby-version
50
+ - .yardopts
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - lib/terminal.rb
56
+ - lib/terminal/api.rb
57
+ - lib/terminal/client.rb
58
+ - lib/terminal/errors.rb
59
+ - lib/terminal/modules/browse_snapshots_and_users.rb
60
+ - lib/terminal/modules/create_and_manage_snapshots.rb
61
+ - lib/terminal/modules/create_and_manage_terminals.rb
62
+ - lib/terminal/modules/request_progress.rb
63
+ - lib/terminal/request.rb
64
+ - lib/terminal/request/encode_json.rb
65
+ - lib/terminal/response/parse_json.rb
66
+ - lib/terminal/response/raise_error_from_json.rb
67
+ - lib/terminal/utils.rb
68
+ - lib/terminal/version.rb
69
+ - spec/fixtures/count_public_snapshots.json
70
+ - spec/fixtures/count_snapshots.json
71
+ - spec/fixtures/delete_snapshot.json
72
+ - spec/fixtures/edit_snapshot.json
73
+ - spec/fixtures/error_response.json
74
+ - spec/fixtures/get_profile.json
75
+ - spec/fixtures/get_snapshot.json
76
+ - spec/fixtures/list_public_snapshots.json
77
+ - spec/fixtures/list_snapshots.json
78
+ - spec/fixtures/list_terminals.json
79
+ - spec/fixtures/request_progress.json
80
+ - spec/helper.rb
81
+ - spec/terminal/client_spec.rb
82
+ - spec/terminal/modules/browse_snapshots_and_users_spec.rb
83
+ - spec/terminal/modules/create_and_manage_snapshots_spec.rb
84
+ - spec/terminal/modules/create_and_manage_terminals_spec.rb
85
+ - spec/terminal/modules/request_progress_spec.rb
86
+ - terminal.gemspec
87
+ homepage: ''
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '2.0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.1.11
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Write a gem summary
111
+ test_files:
112
+ - spec/fixtures/count_public_snapshots.json
113
+ - spec/fixtures/count_snapshots.json
114
+ - spec/fixtures/delete_snapshot.json
115
+ - spec/fixtures/edit_snapshot.json
116
+ - spec/fixtures/error_response.json
117
+ - spec/fixtures/get_profile.json
118
+ - spec/fixtures/get_snapshot.json
119
+ - spec/fixtures/list_public_snapshots.json
120
+ - spec/fixtures/list_snapshots.json
121
+ - spec/fixtures/list_terminals.json
122
+ - spec/fixtures/request_progress.json
123
+ - spec/helper.rb
124
+ - spec/terminal/client_spec.rb
125
+ - spec/terminal/modules/browse_snapshots_and_users_spec.rb
126
+ - spec/terminal/modules/create_and_manage_snapshots_spec.rb
127
+ - spec/terminal/modules/create_and_manage_terminals_spec.rb
128
+ - spec/terminal/modules/request_progress_spec.rb
129
+ has_rdoc: