grabz_it 0.0.1

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.
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: