jarvis-cli 0.0.1 → 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 (45) hide show
  1. checksums.yaml +5 -13
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +6 -0
  4. data/README.md +69 -5
  5. data/bin/jarvis +9 -0
  6. data/features/fact_service.feature +7 -0
  7. data/features/step_definitions/fact_service_steps.rb +7 -0
  8. data/features/step_definitions/server_steps.rb +3 -0
  9. data/features/support/env.rb +38 -0
  10. data/features/support/hooks.rb +1 -0
  11. data/features/support/vcr_cassettes/Fact_Service/Jarvis_responds_with_a_random_fact.yml +52 -0
  12. data/jarvis-cli.gemspec +8 -0
  13. data/lib/jarvis/cli.rb +25 -0
  14. data/lib/jarvis/core_ext/symbol.rb +7 -0
  15. data/lib/jarvis/core_ext.rb +1 -0
  16. data/lib/jarvis/interpreter.rb +32 -0
  17. data/lib/jarvis/server.rb +19 -0
  18. data/lib/jarvis/service.rb +73 -6
  19. data/lib/jarvis/services/dice.rb +25 -0
  20. data/lib/jarvis/services/eightball.rb +38 -0
  21. data/lib/jarvis/services/fact.rb +7 -0
  22. data/lib/jarvis/services/null_service.rb +2 -0
  23. data/lib/jarvis/services.rb +4 -0
  24. data/lib/jarvis/slack/message.rb +17 -0
  25. data/lib/jarvis/slack.rb +1 -0
  26. data/lib/jarvis/test_support/test_support.rb +20 -0
  27. data/lib/jarvis/version.rb +1 -1
  28. data/lib/jarvis.rb +19 -2
  29. data/spec/jarvis/interpreter_spec.rb +61 -0
  30. data/spec/jarvis/jarvis_spec.rb +6 -4
  31. data/spec/jarvis/server_spec.rb +11 -2
  32. data/spec/jarvis/service_spec.rb +93 -14
  33. data/spec/services/dice_spec.rb +22 -0
  34. data/spec/services/eightball_spec.rb +9 -0
  35. data/spec/services/fact_spec.rb +7 -0
  36. data/spec/services/null_service_spec.rb +3 -0
  37. data/spec/spec_helper.rb +53 -0
  38. data/spec/support/fixtures/vcr_cassettes/fact.yml +57 -0
  39. data/spec/support/shared_contexts/server.rb +9 -0
  40. data/spec/support/shared_contexts/service.rb +10 -0
  41. data/templates/project/Gemfile +3 -0
  42. data/templates/project/app/server.rb +2 -0
  43. data/templates/project/app/services/.gitkeep +0 -0
  44. data/templates/project/config.ru +4 -0
  45. metadata +177 -20
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OWI3NjY2OTRkOWIyZmYwZTA2ZGM5ZTc5MTZkNzc0OGNmM2MxOWVlZA==
5
- data.tar.gz: !binary |-
6
- ODc1MGM3OWRkYmM3ZDJlMWU3NzA4N2VhZDJhNDM5NTczY2Q1MWNhMA==
2
+ SHA1:
3
+ metadata.gz: b00e1af36800728f18b6252fcaa52805307dc319
4
+ data.tar.gz: 8cd5db44811394a71a130c41831c8c7835299719
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NDMzMjI2YzQ4YmMzM2I4YzAwYjU1Nzk3MWM2YTJlY2YxNTgxMGNhYmI0Yzdk
10
- NTE5ZDgyNmI1OTM3NTAxY2FlNDgzMzlmMDg2M2RmMDViYzAxMjc2NmUyY2E3
11
- YmZmNTM1YzM4Y2U3NjhmNTY3M2I2OTlmMWU5ODZmNjM5NjJlMTI=
12
- data.tar.gz: !binary |-
13
- ZTEwZWY2ZDM4NzE5MDVmOTNhMGNlOTYxZTBhODZkZDRhNzI5NGY4MjlkYjUy
14
- YTU4NTk1Y2MzMDI4ZTM5ZTgyMTg1YTJkNWRmNGIwMThkZmUzODg2MDM0YTBj
15
- YjIyN2YxNzBiMzcyM2M3ZDMzNjQwYTk0MTI5MDY4NTBkN2Y4YzE=
6
+ metadata.gz: ecff8497b0b166655b85f56a77f9cb832b00b46401fc1ae7a51031ba990d76c7c4778e9125381f637d4b3dbd2d0d809ae5aaa0e0f083bbb1bf5c9d59345a8218
7
+ data.tar.gz: d5e48fd4ff84fb44f92f13bddb58b77051a23d6995a6f1445b56f2671b63aefb4bb1dbf332c54585aff8b29b8d2464239937d95e68af5d9208e9e1851fc966d6
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.4
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ script:
5
+ - bundle exec rspec
6
+ - bundle exec cucumber
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Jarvis CLI
1
+ # Jarvis CLI [![Build Status](https://travis-ci.org/DVG/jarvis-cli.svg?branch=master)](https://travis-ci.org/DVG/jarvis-cli)
2
2
 
3
3
  ## Warning, these instructions are not true yet, but they will be!
4
4
 
@@ -18,7 +18,7 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- Jarvis is an application framework for building Chat bots to integrate with your Slack chatroom. It ships with a number of useful and funny built-in services, but it also provides and easy DSL for creating your own services.
21
+ Jarvis is an application framework for building Chat bots to integrate with your Slack chat room. It ships with a number of useful and funny built-in services, but it also provides and easy DSL for creating your own services.
22
22
 
23
23
  ### Generating a new chat bot
24
24
 
@@ -34,7 +34,7 @@ $ jarvis new my-bot
34
34
 
35
35
  ```ruby
36
36
  class MyBot < Jarvis::Server
37
- register_services Twitter, ImgFlip, UrbanDictionary, Weather
37
+ register_services :twitter, :img_flip, :urban_dictionary, :weather
38
38
  end
39
39
  ```
40
40
 
@@ -46,12 +46,76 @@ If a Service integrates with an authenticated, third party API, you may need to
46
46
 
47
47
  ```ruby
48
48
  class MyService < Jarvis::Service
49
- required_environment "SERVICE_TOKEN", "SERVICE_SECRET"
49
+ environment :service_token, :service_secret
50
50
  end
51
51
  ```
52
52
 
53
- If a service is Registered in `app/server.rb` but does not have it's expected environment, Jarvis will throw an exception and respond with a polite refusal to execute the service. This message can be set in your Jarvis configuration.
53
+ If a service is Registered in `app/server.rb` but does not have it's expected environment, Jarvis will throw an exception and respond with a polite refusal to execute the service. This message can be set in your Jarvis configuration. The enviornment method will also create a getter method for each environment variable.
54
54
 
55
+ ### Service Routing
56
+
57
+ There are two ways to tell Jarvis to send a given message to a particular service.`interpreter_pattern` and `phrases`
58
+
59
+ ```ruby
60
+ class ImgFlip < Jarvis::Service
61
+ phrases = "success kid", "overly attached girlfriend"
62
+ # will converted to a pattern that looks like /success kid|overly attached girlfriend/i
63
+ end
64
+ class SortingHat < Jarvis::Service
65
+ interpreter_pattern = /sorting hat|where do I belong/i
66
+ end
67
+ ```
68
+
69
+ Setting interpreter pattern directly will take precendence over phrases if you include both.
70
+
71
+ ### Running the Service
72
+
73
+ Services should expose a `run` method. This method will perform whatever actions necessary to fulfill the service and should ultimately return the string that Jarvis will send back to the channel in slack.
74
+
75
+ A very simple service might look like:
76
+
77
+ ```ruby
78
+ class SortingHat < Jarvis::Service
79
+ def run
80
+ [
81
+ "Gryphondor, where dwell the brave of heart!",
82
+ "Slytherine, because you are kind of a jerk"
83
+ ].sample
84
+ end
85
+ end
86
+ ```
87
+
88
+ If you want to use a more semantic name for your service, you can override the method using `invoke_with`
89
+
90
+ ```ruby
91
+ class IJustMetYou < Jarvis::Service
92
+ invoke_with :call_me_maybe
93
+
94
+ def call_me_maybe
95
+ "This is crazy, but here's my number, so call me maybe"
96
+ end
97
+ end
98
+ ```
99
+
100
+ ### Callbacks
101
+
102
+ You can do actions before or after the service is run, but before Jarvis responds. For instance:
103
+
104
+ ```ruby
105
+ class Joke < Jarvis::Service
106
+ before_invoke :setup
107
+ invoke_with :punch
108
+
109
+ def setup
110
+ Slack::Post.new(channel_id, "What do you call a fish with no eyes?").send_message
111
+ sleep 1
112
+ end
113
+
114
+ def punch
115
+ "A FSH!"
116
+ end
117
+ end
118
+ ```
55
119
  ## Contributing
56
120
 
57
121
  1. Fork it ( https://github.com/[my-github-username]/jarvis_server/fork )
data/bin/jarvis CHANGED
@@ -1,3 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'jarvis'
4
+
5
+ require "pathname"
6
+ bin_file = Pathname.new(__FILE__).realpath
7
+ $:.unshift File.expand_path("../../lib", bin_file)
8
+
9
+ require 'jarvis/cli'
10
+
11
+ Jarvis::CLI.source_root(File.expand_path('../../templates', bin_file))
12
+ Jarvis::CLI.start(ARGV)
@@ -0,0 +1,7 @@
1
+ @vcr
2
+ Feature: Fact Service
3
+
4
+ Scenario: Jarvis responds with a random fact
5
+ Given a server is running with the fact service enabled
6
+ When Jarvis recieves the message "Jarvis. fact"
7
+ Then Jarvis will respond with "536 is the number of ways to arrange the pieces of the stomachion puzzle into a square."
@@ -0,0 +1,7 @@
1
+ When(/^Jarvis recieves the message "(.*?)"$/) do |message|
2
+ @response = post("/jarvis", slack_outgoing_message(text: message))
3
+ end
4
+
5
+ Then(/^Jarvis will respond with "(.*?)"$/) do |message|
6
+ expect(parsed_response(@response)).to eq message
7
+ end
@@ -0,0 +1,3 @@
1
+ Given(/^a server is running with the (.+) service enabled$/) do |service|
2
+ Jarvis.register_services service.to_sym
3
+ end
@@ -0,0 +1,38 @@
1
+ require 'cucumber'
2
+ require 'jarvis'
3
+ require 'rack/test'
4
+ require 'byebug'
5
+ require 'json'
6
+ require 'capybara/cucumber'
7
+ require 'vcr'
8
+ require 'webmock'
9
+ require 'jarvis/test_support/test_support'
10
+
11
+
12
+ include Rack::Test::Methods
13
+ include Jarvis::TestSupport
14
+
15
+ Before do
16
+ class Server < Jarvis::Server
17
+ end
18
+ Capybara.app = Server
19
+ end
20
+
21
+ After do
22
+ Object.send :remove_const, :Server
23
+ end
24
+
25
+ VCR.configure do |config|
26
+ config.cassette_library_dir = "features/support/vcr_cassettes"
27
+ config.hook_into :webmock
28
+ end
29
+
30
+ VCR.cucumber_tags do |t|
31
+ t.tag '@vcr', :use_scenario_name => true
32
+ end
33
+
34
+
35
+
36
+ def app
37
+ Server
38
+ end
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,52 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://numbersapi.com/random
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx/1.4.6 (Ubuntu)
23
+ Date:
24
+ - Fri, 20 Feb 2015 15:14:17 GMT
25
+ Content-Type:
26
+ - text/plain; charset="UTF-8"; charset=utf-8
27
+ Content-Length:
28
+ - '64'
29
+ Connection:
30
+ - keep-alive
31
+ X-Powered-By:
32
+ - Express
33
+ Access-Control-Allow-Origin:
34
+ - "*"
35
+ Access-Control-Allow-Headers:
36
+ - X-Requested-With
37
+ X-Numbers-Api-Number:
38
+ - '149000000'
39
+ X-Numbers-Api-Type:
40
+ - trivia
41
+ Pragma:
42
+ - no-cache
43
+ Cache-Control:
44
+ - no-cache
45
+ Expires:
46
+ - '0'
47
+ body:
48
+ encoding: UTF-8
49
+ string: 536 is the number of ways to arrange the pieces of the stomachion puzzle into a square.
50
+ http_version:
51
+ recorded_at: Fri, 20 Feb 2015 15:14:02 GMT
52
+ recorded_with: VCR 2.9.3
data/jarvis-cli.gemspec CHANGED
@@ -20,7 +20,15 @@ Gem::Specification.new do |spec|
20
20
  spec.add_development_dependency "bundler", "~> 1.6"
21
21
  spec.add_development_dependency "rake"
22
22
  spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "byebug"
24
+ spec.add_development_dependency "vcr"
25
+ spec.add_development_dependency "webmock"
26
+ spec.add_development_dependency "cucumber"
27
+ spec.add_development_dependency "capybara"
23
28
  spec.add_dependency "sinatra"
24
29
  spec.add_dependency "sinatra-contrib"
25
30
  spec.add_dependency "httparty"
31
+ spec.add_dependency "thor"
32
+ spec.add_dependency "activesupport"
33
+ spec.add_dependency "hooks"
26
34
  end
data/lib/jarvis/cli.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'thor'
2
+ module Jarvis
3
+ class CLI < Thor
4
+ include Thor::Actions
5
+
6
+ desc "new BOT_NAME", "Sets up a new Jarvis project"
7
+ def new(name)
8
+ @name = Thor::Util.snake_case(name)
9
+ directory(:project, @name)
10
+ end
11
+
12
+ desc "boot", "Bootup the Jarvis Application"
13
+ def boot(*args)
14
+ port_option = args.include?('-p') ? '' : ' -p 3030'
15
+ command = "rackup #{port_option}"
16
+ run_command(command)
17
+ end
18
+
19
+ private
20
+
21
+ def run_command(command)
22
+ system(command)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_support/core_ext'
2
+
3
+ class Symbol
4
+ def constantize
5
+ self.to_s.camelize.constantize
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'jarvis/core_ext/symbol'
@@ -0,0 +1,32 @@
1
+ module Jarvis
2
+ class Interpreter
3
+ attr_accessor :slack_message, :text
4
+ def initialize(slack_message)
5
+ @slack_message = slack_message
6
+ @text = slack_message.text
7
+ end
8
+
9
+
10
+ private
11
+
12
+ def self.build_determine_service
13
+ determine_service = <<-code
14
+ def determine_service
15
+ case text
16
+ code
17
+ Jarvis.services.each do |service|
18
+ constant = service.constantize
19
+ determine_service += <<-code
20
+ when #{constant.interpreter_pattern.inspect} then #{constant}
21
+ code
22
+ end
23
+ determine_service += <<-code
24
+ else
25
+ NullService
26
+ end
27
+ end
28
+ code
29
+ self.class_eval determine_service
30
+ end
31
+ end
32
+ end
data/lib/jarvis/server.rb CHANGED
@@ -9,6 +9,25 @@ module Jarvis
9
9
  json text: "Hello, I'm Jarvis"
10
10
  end
11
11
 
12
+ post "/jarvis" do
13
+ message = Slack::Message.new(params)
14
+ service = Jarvis::Interpreter.new(message).determine_service.new(message)
15
+ begin
16
+ json text: run_service(service)
17
+ rescue Jarvis::UnfitEnvironmentException => e
18
+ json text: "I'm really sorry, but that sevice needs to be configured"
19
+ rescue => e
20
+ json text: "I'm sorry, Something went wrong"
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def run_service(service)
27
+ service.validate_environment
28
+ service.invoke
29
+ end
30
+
12
31
  run! if app_file == $0
13
32
  end
14
33
  end
@@ -1,16 +1,83 @@
1
+ require 'hooks'
1
2
  module Jarvis
2
3
  class Service
3
- class << self
4
- attr_accessor :required_environment_variables
5
- def required_environment(*args)
6
- @required_environment_variables = args
7
- end
4
+ include Hooks
5
+
6
+ attr_accessor :message, :response
7
+ def initialize(message)
8
+ @message = message
9
+ @response = ""
10
+ end
11
+
12
+ def method_missing(name, *args, &blk)
13
+ message.public_send(name, *args, &blk)
14
+ end
15
+
16
+ def run
17
+
8
18
  end
9
19
 
10
20
  def validate_environment
11
21
  self.class.required_environment_variables.each do |v|
12
- raise UnfitEnvironmentException unless ENV[v]
22
+ raise UnfitEnvironmentException unless (ENV[v] || ENV[v.downcase])
13
23
  end
14
24
  end
25
+
26
+ # Class Methods
27
+ class << self
28
+ attr_accessor :required_environment_variables, :interpreter_pattern, :phrases, :invoker
29
+
30
+ def phrases=(*args)
31
+ @phrases = args
32
+ reset_interpreter_pattern
33
+ end
34
+
35
+ def required_environment_variables
36
+ @required_environment_variables ||= []
37
+ end
38
+
39
+ def environment(*args)
40
+ args.each do |sym|
41
+ str = sym.to_s.upcase
42
+ send :define_method, sym do
43
+ ENV[str] || ENV[str.downcase]
44
+ end
45
+ required_environment_variables << str
46
+ end
47
+ end
48
+
49
+ def interpreter_pattern
50
+ @interpreter_pattern ||= concatenate_phrases_into_regex
51
+ end
52
+ # class MyService < Jarvis::Service
53
+ # invoke_with :post_tweet
54
+ #
55
+ # end
56
+ def invoke_with(method_name)
57
+ send :define_method, :invoke do
58
+ run_hook :before_invoke
59
+ response = send method_name
60
+ run_hook :after_invoke
61
+ response
62
+ end
63
+ end
64
+
65
+
66
+ private
67
+
68
+ def concatenate_phrases_into_regex
69
+ case self.phrases
70
+ when Array then /#{self.phrases.join("|")}/i
71
+ when String then /#{self.phrases}/i
72
+ end
73
+ end
74
+
75
+ def reset_interpreter_pattern
76
+ @interpreter_pattern = nil
77
+ end
78
+ end
79
+
80
+ invoke_with :run
81
+ define_hooks :before_invoke, :after_invoke
15
82
  end
16
83
  end
@@ -0,0 +1,25 @@
1
+ class Dice < Jarvis::Service
2
+ attr_accessor :dice_result
3
+ phrases = "roll", "dice"
4
+ before_invoke :perform_roll
5
+
6
+ def run
7
+ "You got a #{dice_result}"
8
+ end
9
+
10
+ private
11
+
12
+ def perform_roll
13
+ input = extract_dice_expression.split("d").map(&:to_i)
14
+ self.dice_result = input[0].times.map{ roll input[1] }.inject(:+)
15
+ end
16
+
17
+ def extract_dice_expression
18
+ text[/(\d+[d]\d+)/]
19
+ end
20
+
21
+ def roll(sides)
22
+ Random.rand(sides)
23
+ end
24
+
25
+ end
@@ -0,0 +1,38 @@
1
+ class Eightball < Jarvis::Service
2
+
3
+ interpreter_pattern = /\?$/
4
+
5
+ def run
6
+ responses.sample
7
+ end
8
+
9
+ private
10
+
11
+ def responses
12
+ [
13
+ "It is certain",
14
+ "It is decidedly so",
15
+ "Without a doubt",
16
+ "Yes definitely",
17
+ "You may rely on it",
18
+ "As I see it, yes",
19
+ "Most likely",
20
+ "Outlook good",
21
+ "Yes",
22
+ "Signs point to yes",
23
+ "Reply hazy try again",
24
+ "Ask again later",
25
+ "Better not tell you now",
26
+ "Cannot predict now",
27
+ "Concentrate and ask again",
28
+ "Don't count on it",
29
+ "My reply is no",
30
+ "My sources say no",
31
+ "Outlook not so good",
32
+ "Very doubtful",
33
+ "I dont even",
34
+ "NO",
35
+ "Seriously?"
36
+ ]
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ class Fact < Jarvis::Service
2
+ self.phrases = "fact"
3
+
4
+ def run
5
+ Jarvis.get("http://numbersapi.com/random").parsed_response
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ class NullService < Jarvis::Service
2
+ end
@@ -0,0 +1,4 @@
1
+ require 'jarvis/services/null_service'
2
+ require 'jarvis/services/dice'
3
+ require 'jarvis/services/eightball'
4
+ require 'jarvis/services/fact'
@@ -0,0 +1,17 @@
1
+ module Slack
2
+ class Message
3
+
4
+ attr_accessor :text, :channel_id, :team_id, :channel_name, :user_id, :user_name, :trigger_word
5
+
6
+ def initialize(params)
7
+ @text = params["text"]
8
+ @channel_id = params["channel_id"]
9
+ @team_id = params["team_id"]
10
+ @channel_name = params["channel_name"]
11
+ @user_id = params["user_id"]
12
+ @user_name = params["user_name"]
13
+ @trigger_word = params["trigger_word"]
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1 @@
1
+ require 'jarvis/slack/message'
@@ -0,0 +1,20 @@
1
+ module Jarvis
2
+ module TestSupport
3
+ def slack_outgoing_message(options={text:"Jarvis, what's going on?"})
4
+ {
5
+ "team_id" => options[:team_id] || "T0001",
6
+ "channel_id" => options[:channel_id] || "BLAH",
7
+ "channel_name" => options[:channel_name] || "test",
8
+ "timestamp" => options[:timestamp] || "1355517523.000005",
9
+ "user_id" => options[:user_id] || "U2147483697",
10
+ "user_name" => options[:user_name] || "Steve",
11
+ "text" => options[:text],
12
+ "trigger_word" => options[:trigger_word] || "Jarvis"
13
+ }
14
+ end
15
+
16
+ def parsed_response(response)
17
+ JSON.parse(response.body)["text"]
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Jarvis
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/jarvis.rb CHANGED
@@ -1,9 +1,17 @@
1
+ require 'active_support'
2
+ require 'jarvis/core_ext'
1
3
  require "jarvis/version"
2
4
  require 'jarvis/server'
3
5
  require 'jarvis/service'
4
6
  require 'jarvis/exceptions'
7
+ require 'jarvis/interpreter'
8
+ require 'jarvis/services'
9
+ require 'jarvis/slack'
10
+ require 'httparty'
11
+ require 'uri'
5
12
 
6
13
  module Jarvis
14
+ include HTTParty
7
15
  class << self
8
16
 
9
17
  attr_accessor :services
@@ -11,8 +19,17 @@ module Jarvis
11
19
  @services ||= []
12
20
  end
13
21
 
14
- def register(klass)
15
- services << klass
22
+ def register_services(*args)
23
+ args.each { |klass| services << klass}
24
+ Jarvis::Interpreter.build_determine_service
25
+ end
26
+
27
+ def clear_services
28
+ @services = []
29
+ end
30
+
31
+ def get(*args, &blk)
32
+ HTTParty.get(*args, &blk)
16
33
  end
17
34
 
18
35
  end