grabz_it 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in grabz_it.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 TODO: Write your name
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.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # GrabzIt
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'grabz_it'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install grabz_it
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/grabz_it.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/grabz_it/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Eric Berry"]
6
+ gem.email = ["cavneb@gmail.com"]
7
+ gem.description = "Ruby interface to the GrabzIt (grabz.it) service"
8
+ gem.summary = "Ruby interface to the GrabzIt (grabz.it) service"
9
+ gem.homepage = "https://github.com/cavneb/grabz_it"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "grabz_it"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = GrabzIt::VERSION
17
+
18
+ gem.add_development_dependency('rspec')
19
+ end
data/image ADDED
Binary file
@@ -0,0 +1,251 @@
1
+ module GrabzIt
2
+ class Client
3
+ attr_accessor :app_key, :app_secret, :url, :callback_url, :browser_width, :browser_height,
4
+ :output_width, :output_height, :custom_id, :format, :delay
5
+
6
+ API_BASE_URL = "http://grabz.it/services/"
7
+
8
+ ##
9
+ # Initialize the +GrabzIt::Client+ class
10
+ #
11
+ # @param [String] app_key Application Key provided by grabz.it
12
+ # @param [String] app_secret Application Secret provided by grabz.it
13
+ #
14
+ # @raise [ArgumentError] Exception raised if the app_key or app_secret is not provided
15
+ #
16
+ def initialize(app_key, app_secret)
17
+ @app_key = app_key
18
+ @app_secret = app_secret
19
+ raise(ArgumentError, "You must provide app_key and app_secret") unless @app_key && @app_secret
20
+ end
21
+
22
+ ##
23
+ # Calls the GrabzIt web service to take the screenshot. Warning, this is a SYNCHONOUS method and can take up to
24
+ # 5 minutes before a response.
25
+ #
26
+ # @param [String] target_path File path that the file should be saved to (including file name and extension)
27
+ # @param [Hash] options Data that is to be passed to the web service
28
+ # @option options [String] :url The URL that the screenshot should be made of
29
+ # @option options [String] :callback_url The handler the GrabzIt web service should call after it has completed its work
30
+ # @option options [String] :custom_id A custom identifier that you can pass through to the screenshot webservice. This will be returned with the callback URL you have specified.
31
+ # @option options [Integer] :browser_width The width of the browser in pixels
32
+ # @option options [Integer] :browser_height The height of the browser in pixels
33
+ # @option options [Integer] :output_width The width of the resulting thumbnail in pixels
34
+ # @option options [Integer] :output_height The height of the resulting thumbnail in pixels
35
+ # @option options [String] :format The format the screenshot should be in: bmp8, bmp16, bmp24, bmp, gif, jpg, png
36
+ # @option options [Integer] :delay The number of milliseconds to wait before taking the screenshot
37
+ #
38
+ # @return [GrabzIt::Response] The parsed response.
39
+ #
40
+ # @example
41
+ # client = GrabzIt::Client.new('TEST_KEY', 'TEST_SECRET')
42
+ # options = {
43
+ # :url => 'http://grabz.it',
44
+ # :callback_url => 'http://example.com/callback',
45
+ # :browser_width => 1024,
46
+ # :browser_height => 768,
47
+ # :output_width => 800,
48
+ # :output_height => 600,
49
+ # :custom_id => '12345',
50
+ # :format => 'png',
51
+ # :delay => 1000
52
+ # }
53
+ # response = client.take_picture(options)
54
+ #
55
+ def save_picture(target_path, options = {})
56
+ response = take_picture(options)
57
+
58
+ # Wait for the response to be ready
59
+ iterations = 0
60
+ while true do
61
+ status = get_status(response.screenshot_id)
62
+
63
+ if status.failed?
64
+ raise "The screenshot did not complete with errors: " + status.message
65
+
66
+ elsif status.available?
67
+ image = get_picture(response.screenshot_id)
68
+ image.save(target_path)
69
+ break
70
+ end
71
+
72
+ # Check again in 1 second with a max of 5 minutes
73
+ if iterations <= (5 * 60)
74
+ sleep(1)
75
+ else
76
+ raise Timeout::Error
77
+ end
78
+ end
79
+
80
+ true
81
+ end
82
+
83
+ ##
84
+ # Calls the GrabzIt web service to take the screenshot.
85
+ #
86
+ # @param [Hash] options Data that is to be passed to the web service
87
+ # @option options [String] :url The URL that the screenshot should be made of
88
+ # @option options [String] :callback_url The handler the GrabzIt web service should call after it has completed its work
89
+ # @option options [String] :custom_id A custom identifier that you can pass through to the screenshot webservice. This will be returned with the callback URL you have specified.
90
+ # @option options [Integer] :browser_width The width of the browser in pixels
91
+ # @option options [Integer] :browser_height The height of the browser in pixels
92
+ # @option options [Integer] :output_width The width of the resulting thumbnail in pixels
93
+ # @option options [Integer] :output_height The height of the resulting thumbnail in pixels
94
+ # @option options [String] :format The format the screenshot should be in: bmp8, bmp16, bmp24, bmp, gif, jpg, png
95
+ # @option options [Integer] :delay The number of milliseconds to wait before taking the screenshot
96
+ #
97
+ # @return [GrabzIt::Response] The parsed response.
98
+ #
99
+ # @example
100
+ # client = GrabzIt::Client.new('TEST_KEY', 'TEST_SECRET')
101
+ # options = {
102
+ # :url => 'http://grabz.it',
103
+ # :callback_url => 'http://example.com/callback',
104
+ # :browser_width => 1024,
105
+ # :browser_height => 768,
106
+ # :output_width => 800,
107
+ # :output_height => 600,
108
+ # :custom_id => '12345',
109
+ # :format => 'png',
110
+ # :delay => 1000
111
+ # }
112
+ # response = client.take_picture(options)
113
+ #
114
+ def take_picture(options = {})
115
+ parse_options(options)
116
+ action = "takepicture.ashx"
117
+ response_body = query_api(action, generate_params)
118
+ response = Response.new(response_body)
119
+ raise response.message if response.message
120
+ response
121
+ end
122
+
123
+ ##
124
+ # Get the current status of a GrabzIt screenshot.
125
+ #
126
+ # @param [String] screenshot_id The id of the screenshot provided by the GrabzIt api
127
+ #
128
+ # @return [GrabzIt::Status] The parsed status.
129
+ #
130
+ # @example
131
+ # client = GrabzIt::Client.new('TEST_KEY', 'TEST_SECRET')
132
+ # status = client.get_status('Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58')
133
+ #
134
+ def get_status(screenshot_id)
135
+ action = "getstatus.ashx"
136
+ response_body = query_api(action, { :id => screenshot_id })
137
+ status = Status.new(response_body)
138
+ raise status.message if status.message
139
+ status
140
+ end
141
+
142
+ ##
143
+ # Get the current status of a GrabzIt screenshot.
144
+ #
145
+ # @param [String] screenshot_id The id of the screenshot provided by the GrabzIt api
146
+ #
147
+ # @return [GrabzIt::Status] The parsed status.
148
+ #
149
+ # @example
150
+ # client = GrabzIt::Client.new('TEST_KEY', 'TEST_SECRET')
151
+ # status = client.get_status('Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58')
152
+ #
153
+ def get_cookies(domain)
154
+ action = "getcookies.ashx"
155
+ sig = Digest::MD5.hexdigest(@app_secret + "|" + domain)
156
+ params = {
157
+ :key => URI.escape(@app_key),
158
+ :domain => URI.escape(domain),
159
+ :sig => sig
160
+ }
161
+ response_body = query_api(action, params)
162
+ cookie_jar = CookieJar.new(response_body)
163
+ raise cookie_jar.message if cookie_jar.message
164
+ cookie_jar
165
+ end
166
+
167
+ ##
168
+ # Get the screenshot image
169
+ #
170
+ # @param [String] screenshot_id The id of the screenshot provided by the GrabzIt api
171
+ #
172
+ # @return [GrabzIt::Image] The image object
173
+ #
174
+ # @example
175
+ # client = GrabzIt::Client.new('TEST_KEY', 'TEST_SECRET')
176
+ # image = client.get_image('Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58')
177
+ # puts image.content_type
178
+ # => 'image/png'
179
+ # puts image.size
180
+ # => 129347
181
+ # image.save("/tmp/myimage.png")
182
+ # File.exist?("/tmp/myimage.png")
183
+ # => true
184
+ #
185
+ def get_picture(screenshot_id)
186
+ action = "getpicture.ashx"
187
+ response = query_api(action, { :id => screenshot_id })
188
+ image = Image.new(response)
189
+ image
190
+ end
191
+
192
+ private
193
+
194
+ # Helper method that performs the request
195
+ def query_api(action, params)
196
+ uri = URI("#{API_BASE_URL}#{action}")
197
+ uri.query = URI.encode_www_form(params)
198
+ res = Net::HTTP.get_response(uri)
199
+ res.body
200
+ end
201
+
202
+ # Convert the options into the instance variable values
203
+ def parse_options(options={})
204
+ options = options.symbolize_keys
205
+ @url = options[:url] || ''
206
+ @callback_url = options[:callback_url] || ''
207
+ @browser_width = options[:browser_width] || ''
208
+ @browser_height = options[:browser_height] || ''
209
+ @output_width = options[:output_width] || ''
210
+ @output_height = options[:output_height] || ''
211
+ @custom_id = options[:custom_id] || ''
212
+ @format = options[:format] || ''
213
+ @delay = options[:delay] || ''
214
+ end
215
+
216
+ # Generate the params that are to be used in the request
217
+ def generate_params
218
+ {
219
+ :key => URI.escape(@app_key),
220
+ :url => URI.escape(@url),
221
+ :width => @output_width,
222
+ :height => @output_height,
223
+ :format => @format,
224
+ :bwidth => @browser_width,
225
+ :bheight => @browser_height,
226
+ :callback => URI.escape(@callback_url),
227
+ :customid => URI.escape(@custom_id),
228
+ :delay => @delay,
229
+ :sig => generate_signature
230
+ }
231
+ end
232
+
233
+ # Generate the signature that is used in the request
234
+ def generate_signature
235
+ sig = []
236
+ sig << @app_secret
237
+ sig << @url
238
+ sig << @callback_url
239
+ sig << @format
240
+ sig << @output_height
241
+ sig << @output_width
242
+ sig << @browser_height
243
+ sig << @browser_width
244
+ sig << @custom_id
245
+ sig << @delay
246
+
247
+ Digest::MD5.hexdigest(sig.join('|'))
248
+ end
249
+
250
+ end
251
+ end
@@ -0,0 +1,5 @@
1
+ module GrabzIt
2
+ class Cookie
3
+ attr_accessor :name, :value, :domain, :path, :http_only, :expires, :type
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ module GrabzIt
2
+ class CookieJar
3
+ attr_accessor :cookies, :message
4
+
5
+ def initialize(xml)
6
+ @cookies = []
7
+ doc = REXML::Document.new(xml)
8
+ @message = doc.root.elements['Message'].text
9
+ begin
10
+ add_cookies(doc.root.elements.to_a("//WebResult/Cookies/Cookie"))
11
+ rescue => ex
12
+ raise "Invalid Response: #{xml}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def add_cookies(xml_cookies)
19
+ xml_cookies.each do |c|
20
+ cookie = Cookie.new
21
+ cookie.name = c.elements['Name'].text
22
+ cookie.value = c.elements['Value'].text
23
+ cookie.domain = c.elements['Domain'].text
24
+ cookie.path = c.elements['Path'].text
25
+ cookie.http_only = (c.elements['HttpOnly'].text == 'True')
26
+ cookie.type = c.elements["Type"].text
27
+ if c.elements['Expires']
28
+ cookie.expires = c.elements['Expires'].text
29
+ end
30
+ @cookies << cookie
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ class Hash
2
+
3
+ # Return a new hash with all keys converted to symbols, as long as
4
+ # they respond to +to_sym+.
5
+ #
6
+ # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys
7
+ # #=> { :name => "Rob", :years => "28" }
8
+ def symbolize_keys
9
+ dup.symbolize_keys!
10
+ end
11
+
12
+ # Destructively convert all keys to symbols, as long as they respond
13
+ # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
14
+ def symbolize_keys!
15
+ keys.each do |key|
16
+ self[(key.to_sym rescue key) || key] = delete(key)
17
+ end
18
+ self
19
+ end
20
+
21
+ def to_params
22
+ params = ''
23
+ stack = []
24
+
25
+ each do |k, v|
26
+ if v.is_a?(Hash)
27
+ stack << [k,v]
28
+ else
29
+ params << "#{k}=#{v}&"
30
+ end
31
+ end
32
+
33
+ stack.each do |parent, hash|
34
+ hash.each do |k, v|
35
+ if v.is_a?(Hash)
36
+ stack << ["#{parent}[#{k}]", v]
37
+ else
38
+ params << "#{parent}[#{k}]=#{v}&"
39
+ end
40
+ end
41
+ end
42
+
43
+ params.chop! # trailing &
44
+ params
45
+ end
46
+
47
+ end
@@ -0,0 +1,20 @@
1
+ module GrabzIt
2
+ class Image
3
+ attr_accessor :image_bytes, :content_type, :size
4
+
5
+ def initialize(response)
6
+ begin
7
+ @image_bytes = response.body
8
+ @size = @image_bytes ? @image_bytes.size : 0
9
+ @content_type = response.header['content-type']
10
+ rescue => ex
11
+ raise "Invalid Response"
12
+ end
13
+ end
14
+
15
+ def save(path)
16
+ File.open(path, 'wb') { |s| s.write(@image_bytes) }
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module GrabzIt
2
+ class Response
3
+ attr_accessor :result, :screenshot_id, :message
4
+
5
+ def initialize(xml)
6
+ doc = REXML::Document.new(xml)
7
+ @result = doc.root.elements['Result'].text
8
+ @screenshot_id = doc.root.elements['ID'].text
9
+ @message = doc.root.elements['Message'].text
10
+ end
11
+
12
+ def successful?
13
+ @result == 'True'
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module GrabzIt
2
+ class Status
3
+ attr_accessor :processing, :cached, :expired, :message
4
+
5
+ def initialize(xml)
6
+ doc = REXML::Document.new(xml)
7
+ @processing = (doc.root.elements['Processing'].text == 'True')
8
+ @cached = (doc.root.elements['Cached'].text == 'True')
9
+ @expired = (doc.root.elements['Expired'].text == 'True')
10
+ @message = doc.root.elements['Message'].text
11
+ end
12
+
13
+ def failed?
14
+ !@processing && !@cached
15
+ end
16
+
17
+ def available?
18
+ @cached
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module GrabzIt
2
+ VERSION = "0.0.1"
3
+ end
data/lib/grabz_it.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'rexml/document'
2
+ require 'digest/md5'
3
+ require 'uri'
4
+ require 'net/http'
5
+
6
+ Dir[File.join(File.dirname(__FILE__), "grabz_it", "*rb")].each do |file|
7
+ require file
8
+ end
@@ -0,0 +1,223 @@
1
+ require "spec_helper"
2
+
3
+ describe GrabzIt::Client do
4
+
5
+ it "should raise an error when instanciating without the api_key or api_secret" do
6
+ lambda { GrabzIt::Client.new }.should raise_error(ArgumentError)
7
+ end
8
+
9
+ describe "with a valid api_key and api_secret" do
10
+ before(:each) do
11
+ @client = GrabzIt::Client.new('TEST_KEY', 'TEST_SECRET')
12
+ @options = {
13
+ :url => 'http://grabz.it',
14
+ :callback_url => 'http://example.com/callback',
15
+ :browser_width => 1024,
16
+ :browser_height => 768,
17
+ :output_width => 800,
18
+ :output_height => 600,
19
+ :custom_id => '12345',
20
+ :format => 'png',
21
+ :delay => 1000
22
+ }
23
+ end
24
+
25
+ ## ------------------------------------------------------------------------------------
26
+ # Take Picture
27
+ ## ------------------------------------------------------------------------------------
28
+ it "#take_picture" do
29
+ pending "unable to test without valid app_key and app_secret"
30
+ end
31
+
32
+ ## ------------------------------------------------------------------------------------
33
+ # Take Picture
34
+ ## ------------------------------------------------------------------------------------
35
+ describe "#take_picture" do
36
+ it "with successful response" do
37
+ xml = <<-EOF
38
+ <?xml version="1.0"?>
39
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
40
+ <Result>True</Result>
41
+ <ID>Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58</ID>
42
+ <Message />
43
+ </WebResult>
44
+ EOF
45
+ @client.stub!(:query_api).and_return(xml)
46
+ response = @client.take_picture(@options)
47
+
48
+ response.screenshot_id.should eq('Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58')
49
+ response.successful?.should be_true
50
+ end
51
+
52
+ it "with error response" do
53
+ xml = <<-EOF
54
+ <?xml version="1.0"?>
55
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
56
+ <Result>False</Result>
57
+ <ID />
58
+ <Message>Application Key not recognised.</Message>
59
+ </WebResult>
60
+ EOF
61
+ @client.stub!(:query_api).and_return(xml)
62
+
63
+ lambda{ @client.take_picture(@options) }.should raise_error(RuntimeError, "Application Key not recognised.")
64
+ end
65
+ end
66
+
67
+ ## ------------------------------------------------------------------------------------
68
+ # Get Status
69
+ ## ------------------------------------------------------------------------------------
70
+ describe "#get_status" do
71
+ it "with valid screenshot id" do
72
+ xml = <<-EOF
73
+ <?xml version="1.0"?>
74
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
75
+ <Processing>False</Processing>
76
+ <Cached>True</Cached>
77
+ <Expired>False</Expired>
78
+ <Message />
79
+ </WebResult>
80
+ EOF
81
+ @client.stub!(:query_api).and_return(xml)
82
+ status = @client.get_status('abcde12345')
83
+
84
+ status.processing.should be_false
85
+ status.cached.should be_true
86
+ status.expired.should be_false
87
+ status.message.should be_nil
88
+ end
89
+
90
+ it "with invalid screenshot id" do
91
+ xml = <<-EOF
92
+ <?xml version="1.0"?>
93
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
94
+ <Processing>False</Processing>
95
+ <Cached>False</Cached>
96
+ <Expired>True</Expired>
97
+ <Message />
98
+ </WebResult>
99
+ EOF
100
+ @client.stub!(:query_api).and_return(xml)
101
+ status = @client.get_status('abcde12345')
102
+
103
+ status.processing.should be_false
104
+ status.cached.should be_false
105
+ status.expired.should be_true
106
+ status.message.should be_nil
107
+ end
108
+ end
109
+
110
+ ## ------------------------------------------------------------------------------------
111
+ # Get Picture
112
+ ## ------------------------------------------------------------------------------------
113
+ describe "#get_picture" do
114
+ before(:each) do
115
+ raw_image = File.read(File.join(File.dirname(__FILE__), 'test_data', 'test_image.png'))
116
+ @mocked_response = Struct::MockHTTPResponse.new(raw_image, { 'content-type' => 'image/png' })
117
+ end
118
+
119
+ it "with valid screenshot id" do
120
+ @client.stub!(:query_api).and_return(@mocked_response)
121
+ image = @client.get_picture('YXBAMW9uMS5jb20=-4d164e5166134c31b95cd7b9d23e8ed5')
122
+ image.content_type.should eq('image/png')
123
+ image.size.should eq(129347)
124
+ end
125
+ end
126
+
127
+ ## ------------------------------------------------------------------------------------
128
+ # Get Cookies
129
+ ## ------------------------------------------------------------------------------------
130
+ describe "#get_cookies" do
131
+ it "with valid domain" do
132
+ xml = <<-EOF
133
+ <?xml version="1.0"?>
134
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
135
+ <Cookies>
136
+ <Cookie>
137
+ <Name>secure</Name>
138
+ <Value />
139
+ <Domain>accounts.google.com</Domain>
140
+ <Path>/</Path>
141
+ <HttpOnly>False</HttpOnly>
142
+ <Type>Global</Type>
143
+ </Cookie>
144
+ <Cookie>
145
+ <Name>PREF</Name>
146
+ <Value>ID=c8a1a3e41c52b4ed:TM=1346246013:LM=1346246013:S=_6o6Tap-5lKkES34</Value>
147
+ <Domain>.google.com</Domain>
148
+ <Path>/</Path>
149
+ <HttpOnly>False</HttpOnly>
150
+ <Expires>Sat, 30 Aug 2014 03:13:33 GMT</Expires>
151
+ <Type>Global</Type>
152
+ </Cookie>
153
+ <Cookie>
154
+ <Name>NID</Name>
155
+ <Value>63=zJWKTpnMjJjEhk_9wEEFWYccDWjY7hGrDUfe7csnveQGvD33jdtwOm5fcDh-eHLLwWMlNfzxrM9hwAeWhUkcFNCAjZitNIsewSHf4LCPbfqgaG8eSIMJ7X07p_Gx-bGz</Value>
156
+ <Domain>.google.com</Domain>
157
+ <Path>/</Path>
158
+ <HttpOnly>True</HttpOnly>
159
+ <Expires>Thu, 28 Feb 2013 14:32:20 GMT</Expires>
160
+ <Type>Global</Type>
161
+ </Cookie>
162
+ </Cookies>
163
+ <Message />
164
+ </WebResult>
165
+ EOF
166
+ @client.stub!(:query_api).and_return(xml)
167
+ cookie_jar = @client.get_cookies('google')
168
+ cookie_jar.cookies.size.should eq(3)
169
+ cookie_jar.cookies[0].name.should eq('secure')
170
+ cookie_jar.cookies[0].domain.should eq('accounts.google.com')
171
+ end
172
+
173
+ it "with invalid domain" do
174
+ xml = <<-EOF
175
+ <?xml version="1.0"?>
176
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
177
+ <Cookies />
178
+ <Message />
179
+ </WebResult>
180
+ EOF
181
+ @client.stub!(:query_api).and_return(xml)
182
+ cookie_jar = @client.get_cookies('fsoi')
183
+ cookie_jar.cookies.should be_empty
184
+ end
185
+ end
186
+
187
+ ## ------------------------------------------------------------------------------------
188
+ # Other
189
+ ## ------------------------------------------------------------------------------------
190
+
191
+ it "#parse_options" do
192
+ @client.send(:parse_options, @options)
193
+ @options.each do |k, val|
194
+ @client.send(k).should eq(val)
195
+ end
196
+ end
197
+
198
+ it "#generate_params" do
199
+ @client.send(:parse_options, @options)
200
+ params = @client.send(:generate_params)
201
+
202
+ params[:key].should eq('TEST_KEY')
203
+ params[:url].should eq("http://grabz.it")
204
+ params[:width].should eq(800)
205
+ params[:height].should eq(600)
206
+ params[:format].should eq("png")
207
+ params[:bwidth].should eq(1024)
208
+ params[:bheight].should eq(768)
209
+ params[:callback].should eq("http://example.com/callback")
210
+ params[:customid].should eq("12345")
211
+ params[:delay].should eq(1000)
212
+ params[:sig].should eq("6419e21afbf4d178894bce8dafa91c6d")
213
+ end
214
+
215
+ it "#generate_signature" do
216
+ @client.send(:parse_options, @options)
217
+ signature = @client.send(:generate_signature)
218
+ signature.should eq('6419e21afbf4d178894bce8dafa91c6d')
219
+ end
220
+
221
+ end
222
+
223
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe GrabzIt::Image do
4
+ before(:each) do
5
+ raw_image = File.read(File.join(File.dirname(__FILE__), 'test_data', 'test_image.png'))
6
+ @mocked_response = Struct::MockHTTPResponse.new(raw_image, { 'content-type' => 'image/png' })
7
+ end
8
+
9
+ it "#initialize with successful response" do
10
+ image = GrabzIt::Image.new(@mocked_response)
11
+ image.content_type.should eq('image/png')
12
+ image.size.should eq(129347)
13
+ end
14
+
15
+ it "#initialize with failed response" do
16
+ lambda { image = GrabzIt::Image.new(nil) }.should raise_error(RuntimeError, "Invalid Response")
17
+ end
18
+
19
+ it "#save" do
20
+ image = GrabzIt::Image.new(@mocked_response)
21
+ target = "/tmp/grabz_it_text_image.png"
22
+ saved_image = image.save(target)
23
+ File.exist?(target).should be_true
24
+ File.delete(target) if File.exist?(target) # cleanup
25
+ end
26
+
27
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe GrabzIt::Response do
4
+
5
+ it "#initialize with successful response" do
6
+ xml = <<-EOF
7
+ <?xml version="1.0"?>
8
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
9
+ <Result>True</Result>
10
+ <ID>Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58</ID>
11
+ <Message />
12
+ </WebResult>
13
+ EOF
14
+
15
+ api_response = GrabzIt::Response.new(xml)
16
+ api_response.result.should eq('True')
17
+ api_response.screenshot_id.should eq('Y2F2bmViQGdtYWlsLmNvbQ==-20943258e37c4fc28c4977cd76c40f58')
18
+ api_response.message.should be_nil
19
+ api_response.successful?.should be_true
20
+ end
21
+
22
+ it "#initialize with invalid api key" do
23
+ xml = <<-EOF
24
+ <?xml version="1.0"?>
25
+ <WebResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
26
+ <Result>False</Result>
27
+ <ID />
28
+ <Message>Application Key not recognised.</Message>
29
+ </WebResult>
30
+ EOF
31
+
32
+ api_response = GrabzIt::Response.new(xml)
33
+ api_response.result.should eq('False')
34
+ api_response.screenshot_id.should be_nil
35
+ api_response.message.should eq('Application Key not recognised.')
36
+ api_response.successful?.should be_false
37
+ end
38
+
39
+ end
@@ -0,0 +1,6 @@
1
+ Dir[File.join(File.dirname(__FILE__), "..", "lib", "*.rb")].each do |file|
2
+ require file
3
+ end
4
+
5
+ # Used to mock a response from the web service
6
+ Struct.new "MockHTTPResponse", :body, :header
Binary file
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grabz_it
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Berry
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Ruby interface to the GrabzIt (grabz.it) service
31
+ email:
32
+ - cavneb@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - grabz_it.gemspec
43
+ - image
44
+ - lib/grabz_it.rb
45
+ - lib/grabz_it/client.rb
46
+ - lib/grabz_it/cookie.rb
47
+ - lib/grabz_it/cookie_jar.rb
48
+ - lib/grabz_it/hash.rb
49
+ - lib/grabz_it/image.rb
50
+ - lib/grabz_it/response.rb
51
+ - lib/grabz_it/status.rb
52
+ - lib/grabz_it/version.rb
53
+ - spec/client_spec.rb
54
+ - spec/image_spec.rb
55
+ - spec/response_spec.rb
56
+ - spec/spec_helper.rb
57
+ - spec/test_data/test_image.png
58
+ homepage: https://github.com/cavneb/grabz_it
59
+ licenses: []
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.24
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Ruby interface to the GrabzIt (grabz.it) service
82
+ test_files:
83
+ - spec/client_spec.rb
84
+ - spec/image_spec.rb
85
+ - spec/response_spec.rb
86
+ - spec/spec_helper.rb
87
+ - spec/test_data/test_image.png
88
+ has_rdoc: