superbot-cloud 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Superbot::Cloud
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/superbot/cloud`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ Superbot cloud is a gem that adds cloud functionality for the superbot
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'superbot-cloud'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install superbot-cloud
22
+
23
+ ## Usage
24
+
25
+ Login to the cloud
26
+
27
+ ```ruby
28
+ superbot cloud login
29
+ ```
30
+
31
+ List your organizations from the cloud
32
+
33
+ ```ruby
34
+ superbot cloud org list
35
+ ```
36
+
37
+ Upload test to the cloud
38
+
39
+ ```ruby
40
+ superbot cloud test upload testfolder
41
+ ```
42
+
43
+ For more commands see `superbot cloud --help`
44
+
45
+ ## Development
46
+
47
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
48
+
49
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/superbot-cloud. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
54
+
55
+ ## License
56
+
57
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
58
+
59
+ ## Code of Conduct
60
+
61
+ Everyone interacting in the Superbot::Cloud project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/superbot-cloud/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require 'superbot'
6
+ require "superbot/cloud"
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+
11
+ # (If you use this, don't forget to add pry to your Gemfile!)
12
+ # require "pry"
13
+ # Pry.start
14
+
15
+ require "irb"
16
+ IRB.start(__FILE__)
data/bin/release ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env sh
2
+
3
+ set -e
4
+
5
+ VERSION=$(exe/superbot-cloud version)
6
+ GEM_FILE="superbot-cloud-$VERSION.gem"
7
+
8
+ gem uninstall -a -x superbot-cloud
9
+
10
+ [ -e "$GEM_FILE" ] && rm "$GEM_FILE"
11
+
12
+ gem build superbot-cloud
13
+ gem install superbot-cloud-$VERSION.gem
14
+ VERSION_INSTALLED=$(superbot-cloud version)
15
+
16
+ if [ "$VERSION" != "$VERSION_INSTALLED" ]; then
17
+ echo "!version"
18
+ exit 1
19
+ fi
20
+
21
+ superbot-cloud
22
+
23
+ echo "ok"
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # add lib to libpath (only needed when running from the sources)
5
+ require 'pathname'
6
+ lib_path = File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
7
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
8
+
9
+ STDOUT.sync = true
10
+
11
+ require 'superbot'
12
+ require 'superbot/cloud'
13
+
14
+ Superbot::CLI::CloudCommand.run
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Superbot
4
+ module Cloud
5
+ LOGIN_URI = 'https://superapp-production.herokuapp.com/login/cloud'
6
+ CREDENTIALS_PATH = File.join(Dir.home, '.superbot')
7
+ CREDENTIALS_FILE_PATH = File.join(CREDENTIALS_PATH, 'cloud_token.json')
8
+
9
+ def self.credentials
10
+ return unless File.exist?(CREDENTIALS_FILE_PATH)
11
+
12
+ @credentials ||= JSON.parse(File.read(CREDENTIALS_FILE_PATH), symbolize_names: true)
13
+ end
14
+
15
+ def self.save_credentials(data)
16
+ data.transform_keys!(&:to_sym)
17
+ FileUtils.mkdir_p Superbot::Cloud::CREDENTIALS_PATH
18
+ File.write Superbot::Cloud::CREDENTIALS_FILE_PATH, data.to_json
19
+ "Logged in as #{data[:email]}".tap do |message|
20
+ puts message
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ require_relative "cloud/version"
27
+ require_relative "cloud/api"
28
+ require_relative "cloud/cli"
29
+ require_relative "cloud/web_login"
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http/post/multipart'
4
+
5
+ module Superbot
6
+ module Cloud
7
+ module Api
8
+ BASE_URI = "https://superapp-production.herokuapp.com/api/v1"
9
+ ENDPOINT_MAP = {
10
+ login: { method: :post, endpoint: 'sessions' },
11
+ token: { method: :post, endpoint: 'token' },
12
+ organization_list: { method: :get, endpoint: 'organizations' },
13
+ test_list: { method: :get, endpoint: 'tests' },
14
+ test_upload: { method: :post_multipart, endpoint: 'tests' },
15
+ delete_test: { method: :delete, endpoint: 'tests', required_param: :name }
16
+ }.freeze
17
+
18
+ def self.request(type, params: {})
19
+ method, endpoint, required_param = ENDPOINT_MAP[type].values
20
+ uri = URI.parse([BASE_URI, endpoint, params[required_param]].compact.join('/'))
21
+
22
+ req = Net::HTTP.const_get(
23
+ method.to_s.split('_').map(&:capitalize).join('::')
24
+ ).new(uri, params.compact)
25
+ req.set_form_data(params.compact) unless method == :post_multipart
26
+ if Superbot::Cloud.credentials
27
+ req['Authorization'] = format(
28
+ 'Token token="%<token>s", email="%<email>s"',
29
+ **Superbot::Cloud.credentials.slice(:email, :token)
30
+ )
31
+ end
32
+
33
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
34
+ http.request(req)
35
+ end
36
+ parsed_response = response.class.body_permitted? && JSON.parse(response.body, symbolize_names: true) || {}
37
+ return parsed_response if response.is_a? Net::HTTPSuccess
38
+
39
+ abort parsed_response[:errors]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cli/root_command"
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'launchy'
5
+
6
+ module Superbot
7
+ module CLI
8
+ module Cloud
9
+ class LoginCommand < Clamp::Command
10
+ option ['-i', '--interactive'], :flag, 'interactive login from command line'
11
+ option ['-f', '--force'], :flag, 'force override current credentials'
12
+
13
+ def execute
14
+ return proceed_to_login if force? || Superbot::Cloud.credentials.nil?
15
+
16
+ begin
17
+ Superbot::Cloud::Api.request(:token)
18
+ puts "Logged in as #{Superbot::Cloud.credentials[:email]}"
19
+ rescue SystemExit => e
20
+ abort unless e.message == 'Invalid credentials'
21
+ proceed_to_login
22
+ end
23
+ end
24
+
25
+ def proceed_to_login
26
+ interactive? ? console_login : web_login
27
+ end
28
+
29
+ def console_login
30
+ email = (print 'Email: '; $stdin.gets.rstrip)
31
+ password = (print 'Password: '; $stdin.gets.rstrip)
32
+ api_response = Superbot::Cloud::Api.request(:login, params: { email: email, password: password })
33
+ Superbot::Cloud.save_credentials(api_response)
34
+ end
35
+
36
+ def web_login
37
+ Superbot::Cloud::WebLogin.run!
38
+ Launchy.open(cloud_login_uri)
39
+
40
+ puts "Your browser has been opened to visit:"
41
+ puts cloud_login_uri
42
+ puts ""
43
+ puts "Press enter to exit"
44
+ $stdin.gets
45
+ end
46
+
47
+ def cloud_login_uri
48
+ URI.parse(Superbot::Cloud::LOGIN_URI).tap do |uri|
49
+ uri.query = URI.encode_www_form(redirect_uri: 'http://localhost:4567/login')
50
+ end.to_s
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Superbot
4
+ module CLI
5
+ module Cloud
6
+ module Organization
7
+ class ListCommand < Clamp::Command
8
+ include Superbot::Cloud::Validations
9
+
10
+ def execute
11
+ require_login
12
+ list_organizations
13
+ end
14
+
15
+ def list_organizations
16
+ api_response = Superbot::Cloud::Api.request(:organization_list)
17
+ puts(api_response.map { |org| org[:name] })
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'organization/list_command'
4
+
5
+ module Superbot
6
+ module CLI
7
+ module Cloud
8
+ class OrganizationCommand < Clamp::Command
9
+ subcommand ['list'], "List user organizations from the cloud", Cloud::Organization::ListCommand
10
+
11
+ def self.run
12
+ super
13
+ rescue StandardError => exc
14
+ warn exc.message
15
+ warn exc.backtrace.join("\n")
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Superbot
4
+ module CLI
5
+ module Cloud
6
+ module Test
7
+ class DeleteCommand < Clamp::Command
8
+ include Superbot::Cloud::Validations
9
+
10
+ option ["-o", "--org"], "ORGANIZATION", "Organization to search test for deletion", attribute_name: :organization
11
+ parameter "NAME", "the name of the test to delete", required: true
12
+
13
+ def execute
14
+ require_login
15
+ delete_test
16
+ end
17
+
18
+ def delete_test
19
+ Superbot::Cloud::Api.request(:delete_test, params: { name: name, organization_name: organization })
20
+ puts "Tests successfully deleted"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Superbot
4
+ module CLI
5
+ module Cloud
6
+ module Test
7
+ class ListCommand < Clamp::Command
8
+ include Superbot::Cloud::Validations
9
+
10
+ option ["-o", "--org"], "ORGANIZATION", "Organization to list tests for", attribute_name: :organization
11
+
12
+ def execute
13
+ require_login
14
+ list_tests
15
+ end
16
+
17
+ def list_tests
18
+ api_response = Superbot::Cloud::Api.request(:test_list, params: { organization_name: organization })
19
+ abort api_response[:errors] if api_response[:errors]
20
+ puts "Organization: #{api_response[:organization]}"
21
+ puts "Tests:"
22
+ api_response[:tests].each do |test|
23
+ puts(test[:name], test[:files].map { |f| "- #{f[:filename]}" })
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'net/http/post/multipart'
5
+ require 'marcel'
6
+ require 'pathname'
7
+
8
+ module Superbot
9
+ module CLI
10
+ module Cloud
11
+ module Test
12
+ class UploadCommand < Clamp::Command
13
+ include Superbot::Validations
14
+ include Superbot::Cloud::Validations
15
+
16
+ parameter "PATH", "the path to folder containing tests to upload" do |path|
17
+ validates_project_path path
18
+ end
19
+
20
+ option ["-o", "--org"], "ORGANIZATION", "Organization to upload tests for", attribute_name: :organization
21
+
22
+ def execute
23
+ require_login
24
+ upload_tests
25
+ end
26
+
27
+ def upload_tests
28
+ Dir.glob(File.join(path, '*.rb')) do |test_file|
29
+ puts "Uploading files from #{path}..."
30
+ filename = File.basename(test_file)
31
+ content_type = Marcel::MimeType.for(Pathname.new(test_file), name: filename)
32
+
33
+ File.open(test_file) do |file|
34
+ api_response = Superbot::Cloud::Api.request(
35
+ :test_upload,
36
+ params: {
37
+ name: Zaru.sanitize!(path),
38
+ organization_name: organization,
39
+ file: UploadIO.new(file, content_type, filename)
40
+ }
41
+ )
42
+
43
+ print filename, ' - ', api_response[:errors] || 'Success'
44
+ puts
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'test/list_command'
4
+ require_relative 'test/upload_command'
5
+ require_relative 'test/delete_command'
6
+
7
+ module Superbot
8
+ module CLI
9
+ module Cloud
10
+ class TestCommand < Clamp::Command
11
+ subcommand ['list'], "List user tests from the cloud", Cloud::Test::ListCommand
12
+ subcommand ['upload'], "Upload test to the cloud", Cloud::Test::UploadCommand
13
+ subcommand ['delete'], "Delete test from the cloud", Cloud::Test::DeleteCommand
14
+
15
+ def self.run
16
+ super
17
+ rescue StandardError => exc
18
+ warn exc.message
19
+ warn exc.backtrace.join("\n")
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end