capgun 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/Gemfile +1 -8
- data/Gemfile.lock +32 -0
- data/HISTORY.md +14 -3
- data/LICENSE.md +26 -0
- data/README.md +306 -4
- data/Rakefile +10 -2
- data/capgun.gemspec +27 -16
- data/examples/hubot/capgun.coffee +68 -0
- data/lib/capgun.rb +29 -1
- data/lib/capgun/account.rb +13 -0
- data/lib/capgun/base.rb +48 -0
- data/lib/capgun/client.rb +82 -0
- data/lib/capgun/config.rb +73 -0
- data/lib/capgun/connection.rb +36 -0
- data/lib/capgun/core_ext/hash.rb +19 -0
- data/lib/capgun/creatable.rb +21 -0
- data/lib/capgun/error.rb +17 -0
- data/lib/capgun/error/bad_gateway.rb +7 -0
- data/lib/capgun/error/bad_request.rb +7 -0
- data/lib/capgun/error/client_error.rb +7 -0
- data/lib/capgun/error/forbidden.rb +7 -0
- data/lib/capgun/error/internal_server_error.rb +7 -0
- data/lib/capgun/error/not_acceptable.rb +7 -0
- data/lib/capgun/error/not_found.rb +7 -0
- data/lib/capgun/error/server_error.rb +7 -0
- data/lib/capgun/error/service_unavailable.rb +7 -0
- data/lib/capgun/error/unauthorized.rb +7 -0
- data/lib/capgun/estimate.rb +11 -0
- data/lib/capgun/job.rb +13 -0
- data/lib/capgun/order.rb +13 -0
- data/lib/capgun/request.rb +33 -0
- data/lib/capgun/request/gateway.rb +20 -0
- data/lib/capgun/response/parse_json.rb +28 -0
- data/lib/capgun/response/raise_client_error.rb +48 -0
- data/lib/capgun/response/raise_server_error.rb +23 -0
- data/lib/capgun/version.rb +27 -7
- data/spec/capgun/account_spec.rb +45 -0
- data/spec/capgun/base_spec.rb +29 -0
- data/spec/capgun/client_spec.rb +181 -0
- data/spec/capgun/config_spec.rb +43 -0
- data/spec/capgun/estimate_spec.rb +7 -0
- data/spec/capgun/job_spec.rb +45 -0
- data/spec/capgun/order_spec.rb +45 -0
- data/spec/capgun/version_spec.rb +11 -0
- data/spec/capgun_spec.rb +17 -0
- data/spec/faraday/response_spec.rb +68 -0
- data/spec/fixtures/account.json +9 -0
- data/spec/fixtures/completed-order.json +46 -0
- data/spec/fixtures/estimate.json +34 -0
- data/spec/fixtures/job.json +9 -0
- data/spec/fixtures/notfound.json +1 -0
- data/spec/fixtures/order.json +43 -0
- data/spec/fixtures/unauthorized.json +1 -0
- data/spec/spec_helper.rb +27 -0
- metadata +218 -10
@@ -0,0 +1,68 @@
|
|
1
|
+
# Description
|
2
|
+
# Grab web screens/thumbs of URLs using the capgun.io service
|
3
|
+
#
|
4
|
+
# Requires a CapGun API token to be set in the env var HUBOT_CAPGUN_TOKEN
|
5
|
+
#
|
6
|
+
# Dependencies:
|
7
|
+
# none
|
8
|
+
#
|
9
|
+
# Configuration:
|
10
|
+
# HUBOT_CAPGUN_TOKEN
|
11
|
+
#
|
12
|
+
# Commands:
|
13
|
+
# hubot cap <url> - Get a web screen of the url
|
14
|
+
#
|
15
|
+
# Notes:
|
16
|
+
# none
|
17
|
+
#
|
18
|
+
# Author:
|
19
|
+
# monde
|
20
|
+
|
21
|
+
module.exports = (robot) ->
|
22
|
+
robot.respond /cap (.*)/i, (msg) ->
|
23
|
+
Capgun.start msg, msg.match[1]
|
24
|
+
|
25
|
+
Capgun =
|
26
|
+
|
27
|
+
interval: 2500
|
28
|
+
|
29
|
+
token: process.env.HUBOT_CAPGUN_TOKEN
|
30
|
+
|
31
|
+
start: (msg, url) ->
|
32
|
+
this.submitOrder(msg, url)
|
33
|
+
|
34
|
+
submitOrder: (msg, url) ->
|
35
|
+
capgun = this
|
36
|
+
data = JSON.stringify({"url": url})
|
37
|
+
msg.http('https://api.capgun.io/v1/orders.json')
|
38
|
+
.headers
|
39
|
+
'Authorization': capgun.token,
|
40
|
+
'Accept': 'application/json'
|
41
|
+
.post(data) (err, res, body) ->
|
42
|
+
result = JSON.parse(body)
|
43
|
+
if err || res.statusCode != 200
|
44
|
+
message = result.message || "???"
|
45
|
+
msg.send "Capgun job failed with message '" + message + "', I'm bailing out!"
|
46
|
+
else
|
47
|
+
setTimeout (-> capgun.checkJob(msg, url, result.order.id, 0)), capgun.interval
|
48
|
+
|
49
|
+
checkJob: (msg, url, order_id, duration) ->
|
50
|
+
capgun = this
|
51
|
+
|
52
|
+
if duration > 90000
|
53
|
+
msg.send "Capgun job hung past 90 seconds for URL " + url + " , I'm bailing out!"
|
54
|
+
else
|
55
|
+
msg.http('https://api.capgun.io/v1/orders/' + order_id + '.json')
|
56
|
+
.headers
|
57
|
+
'Authorization': capgun.token,
|
58
|
+
'Accept': 'application/json'
|
59
|
+
.get() (err, res, body) ->
|
60
|
+
result = JSON.parse(body)
|
61
|
+
state = result.order.job.state
|
62
|
+
|
63
|
+
if state.search(/failed/) >= 0
|
64
|
+
msg.send "Capgun order " + order_id + " failed for URL " + url
|
65
|
+
else if state.search(/completed/) >= 0
|
66
|
+
msg.send result.order.asset_urls['640x480']
|
67
|
+
else
|
68
|
+
setTimeout (-> capgun.checkJob(msg, url, result.order.id, duration + capgun.interval)), capgun.interval
|
data/lib/capgun.rb
CHANGED
@@ -1,3 +1,31 @@
|
|
1
1
|
module Capgun
|
2
|
-
|
2
|
+
|
3
|
+
require 'capgun/config'
|
4
|
+
require 'capgun/client'
|
5
|
+
|
6
|
+
extend Config
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
extend Config
|
11
|
+
|
12
|
+
# Alias for Capgun::Client.new
|
13
|
+
#
|
14
|
+
# @param [Hash] options options for the Capgun::Client
|
15
|
+
# @return [Capgun::Client]
|
16
|
+
def new(options={})
|
17
|
+
Capgun::Client.new(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Delegate methods to Capgun::Client
|
21
|
+
def method_missing(method, *args, &block)
|
22
|
+
return super unless new.respond_to?(method)
|
23
|
+
new.send(method, *args, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Corollary of #method_missing delegated to Capgun::Client
|
27
|
+
def respond_to?(method, include_private=false)
|
28
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
29
|
+
end
|
30
|
+
end
|
3
31
|
end
|
data/lib/capgun/base.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'capgun/creatable'
|
2
|
+
|
3
|
+
module Capgun
|
4
|
+
class Base
|
5
|
+
attr_accessor :attrs
|
6
|
+
alias :to_hash :attrs
|
7
|
+
|
8
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
9
|
+
#
|
10
|
+
# @overload self.lazy_attr_reader(attr)
|
11
|
+
# @param attr [Symbol]
|
12
|
+
# @overload self.lazy_attr_reader(attrs)
|
13
|
+
# @param attrs [Array<Symbol>]
|
14
|
+
def self.lazy_attr_reader(*attrs)
|
15
|
+
attrs.each do |attribute|
|
16
|
+
class_eval do
|
17
|
+
define_method attribute do
|
18
|
+
@attrs[attribute.to_s]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Initializes a new Base object
|
25
|
+
#
|
26
|
+
# @param attrs [Hash]
|
27
|
+
# @return [Capgun::Base]
|
28
|
+
def initialize(attrs={})
|
29
|
+
@attrs = attrs.dup
|
30
|
+
end
|
31
|
+
|
32
|
+
# Initializes a new Base object
|
33
|
+
#
|
34
|
+
# @param method [String, Symbol] Message to send to the object
|
35
|
+
def [](method)
|
36
|
+
self.__send__(method.to_sym)
|
37
|
+
rescue NoMethodError
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param other [Capgun::Base]
|
42
|
+
# @return [Boolean]
|
43
|
+
def ==(other)
|
44
|
+
super || (other.class == self.class && other.id == self.id)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'json/pure'
|
3
|
+
require 'capgun/base'
|
4
|
+
require 'capgun/account'
|
5
|
+
require 'capgun/estimate'
|
6
|
+
require 'capgun/job'
|
7
|
+
require 'capgun/order'
|
8
|
+
require 'capgun/config'
|
9
|
+
require 'capgun/connection'
|
10
|
+
require 'capgun/request'
|
11
|
+
|
12
|
+
module Capgun
|
13
|
+
|
14
|
+
# Wrapper for the Capgun REST API
|
15
|
+
class Client
|
16
|
+
|
17
|
+
include Capgun::Connection
|
18
|
+
include Capgun::Request
|
19
|
+
|
20
|
+
attr_accessor *Config::VALID_OPTIONS_KEYS
|
21
|
+
|
22
|
+
# Initializes a new API object. Accessor attributes are set based
|
23
|
+
# on Capgun::Config::VALID_OPTIONS_KEYS
|
24
|
+
#
|
25
|
+
# @param [Hash] attrs Addition client attributes.
|
26
|
+
# @return [Capgun::Client]
|
27
|
+
def initialize(attrs={})
|
28
|
+
attrs = Capgun.options.merge(attrs)
|
29
|
+
Config::VALID_OPTIONS_KEYS.each do |key|
|
30
|
+
instance_variable_set("@#{key}".to_sym, attrs[key])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Estimates a capgun job cost / availability.
|
35
|
+
#
|
36
|
+
# @param [String] url A url that will be captured.
|
37
|
+
# @param [Hash] options Additional options to the capture request.
|
38
|
+
# @return [Capgun::Estimate] The estimate for the capture request.
|
39
|
+
def estimate(url, options = {})
|
40
|
+
estimate = post("/v1/orders/estimate.json", options.merge(:url => url))
|
41
|
+
Capgun::Estimate.new(estimate['order'])
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creates a capgun job
|
45
|
+
#
|
46
|
+
# @param [String] url A url that will be captured.
|
47
|
+
# @param [Hash] options Additional options to the capture request.
|
48
|
+
# @return [Capgun::Order] The capture request order.
|
49
|
+
def capture(url, options = {})
|
50
|
+
order = post("/v1/orders.json", options.merge(:url => url))
|
51
|
+
Capgun::Order.new(order['order'])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Query the order
|
55
|
+
#
|
56
|
+
# @param [String] order_id The id of a previously submitted order.
|
57
|
+
# @return [Capgun::Order] The capture order.
|
58
|
+
def order(order_id)
|
59
|
+
order = get("/v1/orders/#{order_id}.json")
|
60
|
+
Capgun::Order.new(order['order'])
|
61
|
+
end
|
62
|
+
|
63
|
+
# Query the status of a capture job.
|
64
|
+
#
|
65
|
+
# @param [String] job_id The id of a previously submitted capture job.
|
66
|
+
# @return [Capgun::Job] The capture request is a job that encapsulates status.
|
67
|
+
def status(job_id)
|
68
|
+
job = get("/v1/jobs/#{job_id}.json")
|
69
|
+
Capgun::Job.new(job['job'])
|
70
|
+
end
|
71
|
+
|
72
|
+
# Fetch account information
|
73
|
+
#
|
74
|
+
# @return [Capgun::Account] The account
|
75
|
+
def account
|
76
|
+
account = get("/v1/account.json")
|
77
|
+
Capgun::Account.new(account['account'])
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'capgun/version'
|
2
|
+
|
3
|
+
module Capgun
|
4
|
+
|
5
|
+
# Defines constants and methods related to configuration
|
6
|
+
module Config
|
7
|
+
|
8
|
+
# The HTTP connection adapter that will be used to connect if none is set
|
9
|
+
DEFAULT_ADAPTER = :net_http
|
10
|
+
|
11
|
+
# The Faraday connection options if none is set
|
12
|
+
DEFAULT_CONNECTION_OPTIONS = {}
|
13
|
+
|
14
|
+
# API endpoint
|
15
|
+
DEFAULT_ENDPOINT = 'https://api.capgun.io'
|
16
|
+
|
17
|
+
# The gateway server if none is set
|
18
|
+
DEFAULT_GATEWAY = nil
|
19
|
+
|
20
|
+
# The auth token if none is set
|
21
|
+
DEFAULT_AUTH_TOKEN = ""
|
22
|
+
|
23
|
+
# The value sent in the 'User-Agent' header if none is set
|
24
|
+
DEFAULT_USER_AGENT = "Capgun.io Ruby Gem #{Capgun::Version}"
|
25
|
+
|
26
|
+
# The proxy server if none is set
|
27
|
+
DEFAULT_PROXY = nil
|
28
|
+
|
29
|
+
# An array of valid keys in the options hash when configuring a {Capgun::Client}
|
30
|
+
VALID_OPTIONS_KEYS = [
|
31
|
+
:adapter,
|
32
|
+
:connection_options,
|
33
|
+
:endpoint,
|
34
|
+
:gateway,
|
35
|
+
:auth_token,
|
36
|
+
:user_agent,
|
37
|
+
:proxy,
|
38
|
+
]
|
39
|
+
|
40
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
41
|
+
|
42
|
+
# When this module is extended, set all configuration options to their default values
|
43
|
+
def self.extended(base)
|
44
|
+
base.reset
|
45
|
+
end
|
46
|
+
|
47
|
+
# Convenience method to allow configuration options to be set in a block
|
48
|
+
def configure
|
49
|
+
yield self
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create a hash of options and their values
|
54
|
+
def options
|
55
|
+
options = {}
|
56
|
+
VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
|
57
|
+
options
|
58
|
+
end
|
59
|
+
|
60
|
+
# Reset all configuration options to defaults
|
61
|
+
def reset
|
62
|
+
self.adapter = DEFAULT_ADAPTER
|
63
|
+
self.connection_options = DEFAULT_CONNECTION_OPTIONS
|
64
|
+
self.endpoint = DEFAULT_ENDPOINT
|
65
|
+
self.gateway = DEFAULT_GATEWAY
|
66
|
+
self.auth_token = DEFAULT_AUTH_TOKEN
|
67
|
+
self.user_agent = DEFAULT_USER_AGENT
|
68
|
+
self.proxy = DEFAULT_PROXY
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'capgun/core_ext/hash'
|
3
|
+
require 'capgun/request/gateway'
|
4
|
+
require 'capgun/response/parse_json'
|
5
|
+
require 'capgun/response/raise_client_error'
|
6
|
+
require 'capgun/response/raise_server_error'
|
7
|
+
|
8
|
+
module Capgun
|
9
|
+
module Connection
|
10
|
+
private
|
11
|
+
|
12
|
+
# Returns a Faraday::Connection object
|
13
|
+
#
|
14
|
+
# @param options [Hash] A hash of options
|
15
|
+
# @return [Faraday::Connection]
|
16
|
+
def connection(options={})
|
17
|
+
default_options = {
|
18
|
+
:headers => {
|
19
|
+
:accept => 'application/json',
|
20
|
+
:user_agent => user_agent,
|
21
|
+
:authorization => auth_token,
|
22
|
+
},
|
23
|
+
:proxy => proxy,
|
24
|
+
:ssl => {:verify => false},
|
25
|
+
:url => options.fetch(:endpoint, endpoint),
|
26
|
+
}
|
27
|
+
@connection ||=Faraday.new(default_options.deep_merge(connection_options)) do |builder|
|
28
|
+
builder.use Capgun::Request::Gateway, gateway if gateway
|
29
|
+
builder.use Capgun::Response::RaiseClientError
|
30
|
+
builder.use Capgun::Response::ParseJson
|
31
|
+
builder.use Capgun::Response::RaiseServerError
|
32
|
+
builder.adapter(adapter)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Merges self with another hash, recursively
|
4
|
+
#
|
5
|
+
# @param hash [Hash] The hash to merge
|
6
|
+
# @return [Hash]
|
7
|
+
def deep_merge(hash)
|
8
|
+
target = self.dup
|
9
|
+
hash.keys.each do |key|
|
10
|
+
if hash[key].is_a?(Hash) && self[key].is_a?(Hash)
|
11
|
+
target[key] = target[key].deep_merge(hash[key])
|
12
|
+
next
|
13
|
+
end
|
14
|
+
target[key] = hash[key]
|
15
|
+
end
|
16
|
+
target
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Capgun
|
4
|
+
module Creatable
|
5
|
+
|
6
|
+
# Time when the object was created
|
7
|
+
#
|
8
|
+
# @return [Time]
|
9
|
+
def created_at
|
10
|
+
@created_at ||= Time.parse(@attrs['created_at']) unless @attrs['created_at'].nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
# Time when the object was updated
|
14
|
+
#
|
15
|
+
# @return [Time]
|
16
|
+
def updated_at
|
17
|
+
@updated_at ||= Time.parse(@attrs['updated_at']) unless @attrs['updated_at'].nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/capgun/error.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Capgun
|
2
|
+
# Custom error class for rescuing from all Capgun errors
|
3
|
+
class Error < StandardError
|
4
|
+
attr_reader :http_headers
|
5
|
+
|
6
|
+
# Initializes a new Error object
|
7
|
+
#
|
8
|
+
# @param message [String]
|
9
|
+
# @param http_headers [Hash]
|
10
|
+
# @return [Capgun::Error]
|
11
|
+
def initialize(message, http_headers)
|
12
|
+
@http_headers = Hash[http_headers]
|
13
|
+
super(message)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|