restful_press 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Gemini SBS, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,71 @@
1
+ = Resftul Press
2
+
3
+ Ruby client for the Resful Press API. Uses the YAJL library for fast JSON decoding.
4
+
5
+ == About Restful Press
6
+
7
+ Restful Press is an automated service for converting your app's views into PDFs. There is no special PDF DSL required.
8
+ You simply write your views in HAML, ERB or Mustache as you always have and Restful Press takes care of the rest.
9
+
10
+ Each request to render your PDF is referred to as a *job* by the Restful Press service. This client follows that nomenclature.
11
+
12
+ == Install
13
+
14
+ gem install restful_press
15
+
16
+ == Usage
17
+
18
+ === Initialize the client
19
+
20
+ require 'restful_press'
21
+ ➔ true
22
+
23
+ RestfulPress::Client.set_credentials('my_api_key')
24
+ ➔ true
25
+
26
+ === View your jobs
27
+
28
+ RestfulPress::Client.get_jobs
29
+ ➔ [{:complete=>false, :id=>9, :filename=>"export.pdf"}, {:complete=>true, :id=>10, :filename=>"products.pdf"}]
30
+
31
+ RestfulPress::Client.get_job(9)
32
+ ➔ {:complete=>false, :id=>9, :filename=>"export.pdf"}
33
+
34
+ RestfulPress::Client.job_url(9)
35
+ ➔ "http://restfulpress.com/jobs/9/download"
36
+
37
+ RestfulPress::Client.job_complete?(9)
38
+ ➔ false
39
+
40
+ === Deleting jobs
41
+
42
+ RestfulPress::Client.delete_job(9)
43
+ ➔ true
44
+
45
+ === Creating Jobs
46
+
47
+ RestfulPress::Client.add_job(:html_doc => "<html><h1>Hello,</h1> this is a test</html>", :pdf_options => { :page_size => "Letter" })
48
+ ➔ true
49
+
50
+ Note: For a full list of supported PDF options, please see the *Supported PDF Options* section of this document
51
+
52
+ == Integration with Rails
53
+
54
+ Coming soon.
55
+
56
+ == Supported PDF Options
57
+
58
+ Coming soon.
59
+
60
+ == Dependencies
61
+
62
+ * {yajl-ruby}[http://github.com/brianmario/yajl-ruby] (Ruby wrapper around the great {yajl}[http://lloyd.github.com/yajl])
63
+ * {rest-client}[http://github.com/archiloque/rest-client]
64
+
65
+ == Copyright
66
+
67
+ Copyright (c) 2010 Gemini SBS. See LICENSE for details.
68
+
69
+ == Authors
70
+
71
+ * {Mauricio Gomes}[http://github.com/mgomes]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,23 @@
1
+ require 'uri'
2
+ require 'yajl'
3
+ require 'rest_client'
4
+
5
+ require 'restful_press/connection'
6
+ require 'restful_press/endpoint'
7
+ require 'restful_press/hash_utils'
8
+ require 'restful_press/client'
9
+
10
+ module RestfulPress
11
+ REALM = "http://quick-pdf.geminisbs.net"
12
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
13
+
14
+ class RestfulPressError < StandardError; end
15
+ class Unauthorized < RestfulPressError; end
16
+ class NotFound < RestfulPressError; end
17
+ class APIKeyExpired < RestfulPressError; end
18
+ class MethodNotAllowed < RestfulPressError; end
19
+ class ServerError < RestfulPressError; end
20
+ class Unavailable < RestfulPressError; end
21
+ class DecodeError < RestfulPressError; end
22
+ class NoConnectionEstablished < RestfulPressError; end
23
+ end
@@ -0,0 +1,100 @@
1
+ module RestfulPress
2
+
3
+ class Client
4
+
5
+ @@connection = nil
6
+ @@debug = false
7
+
8
+ class << self
9
+
10
+ def set_credentials(api_key)
11
+ @@connection = Connection.new(api_key)
12
+ @@connection.debug = @@debug
13
+ true
14
+ end
15
+
16
+ def debug=(debug_flag)
17
+ @@debug = debug_flag
18
+ @@connection.debug = @@debug if @@connection
19
+ end
20
+
21
+ def debug
22
+ @@debug
23
+ end
24
+
25
+ def add_job(*args)
26
+ options = extract_options!(args)
27
+ params = Hash.new
28
+ params[:job] = options
29
+
30
+ response = post(Endpoint.jobs, params)
31
+ HashUtils.recursively_symbolize_keys(response)
32
+ end
33
+
34
+ def get_job(id)
35
+ response = get(Endpoint.job(id))
36
+ HashUtils.recursively_symbolize_keys(response)
37
+ end
38
+
39
+ def get_jobs
40
+ response = get(Endpoint.jobs)
41
+ HashUtils.recursively_symbolize_keys(response)
42
+ end
43
+
44
+ def delete_job(id)
45
+ response = delete(Endpoint.job(id))
46
+ if response.nil?
47
+ return true
48
+ else
49
+ HashUtils.recursively_symbolize_keys(response)
50
+ end
51
+ end
52
+
53
+ def job_url(id)
54
+ Endpoint.download_job(id)
55
+ end
56
+
57
+ def job_download(id)
58
+ response = get(Endpoint.download_job(id))
59
+ HashUtils.recursively_symbolize_keys(response)
60
+ end
61
+
62
+ def job_complete?(id)
63
+ get_job(id)[:complete]
64
+ end
65
+
66
+ def get(endpoint, data=nil)
67
+ raise NoConnectionEstablished if @@connection.nil?
68
+ @@connection.get endpoint, data
69
+ end
70
+
71
+ def delete(endpoint, data=nil)
72
+ raise NoConnectionEstablished if @@connection.nil?
73
+ @@connection.delete endpoint, data
74
+ end
75
+
76
+ def post(endpoint, data=nil)
77
+ raise NoConnectionEstablished if @@connection.nil?
78
+ @@connection.post endpoint, data
79
+ end
80
+
81
+ def put(endpoint, data=nil)
82
+ raise NoConnectionEstablished if @@connection.nil?
83
+ @@connection.put endpoint, data
84
+ end
85
+
86
+ private
87
+
88
+ def extract_options!(args)
89
+ if args.last.is_a?(Hash)
90
+ return args.pop
91
+ else
92
+ return {}
93
+ end
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,139 @@
1
+ module RestfulPress
2
+
3
+ class Connection
4
+
5
+ attr_accessor :debug
6
+ attr_reader :api_key, :default_options
7
+
8
+ def initialize(api_key)
9
+ @api_key = api_key
10
+ @default_options = { :api_key => @api_key }
11
+ @debug = false
12
+ end
13
+
14
+ def get(endpoint, data=nil)
15
+ request :get, endpoint, data
16
+ end
17
+
18
+ def delete(endpoint, data=nil)
19
+ request :delete, endpoint, data
20
+ end
21
+
22
+ def post(endpoint, data=nil)
23
+ request :post, endpoint, data
24
+ end
25
+
26
+ def put(endpoint, data=nil)
27
+ request :put, endpoint, data
28
+ end
29
+
30
+ private
31
+
32
+ def request(method, endpoint, data=nil)
33
+ headers = { 'User-Agent' => "RestfulPress Ruby Client v#{VERSION}",
34
+ 'Content-Type' => "application/json"
35
+ }
36
+
37
+ if data.nil?
38
+ data = @default_options
39
+ else
40
+ data.merge!(@default_options)
41
+ end
42
+
43
+ if [:get, :delete].include?(method)
44
+ endpoint = endpoint + '?' + build_query(data)
45
+ end
46
+
47
+ if debug
48
+ puts "request: #{method.to_s.upcase} #{endpoint}"
49
+ puts "headers:"
50
+ headers.each do |key, value|
51
+ puts "#{key}=#{value}"
52
+ end
53
+ if [:post, :put].include?(method)
54
+ puts "data:"
55
+ puts Yajl::Encoder.encode data
56
+ end
57
+ end
58
+
59
+ case method
60
+ when :get, :delete
61
+ response = send_request(method, endpoint, headers)
62
+ when :post, :put
63
+ data = Yajl::Encoder.encode data
64
+ response = send_request(method, endpoint, headers, data)
65
+ end
66
+
67
+ if debug
68
+ puts "\nresponse: #{response.code}"
69
+ puts "headers:"
70
+ response.header.each do |key, value|
71
+ puts "#{key}=#{value}"
72
+ end
73
+ puts "body:"
74
+ puts response.body
75
+ end
76
+
77
+ if response.body.empty?
78
+ content = nil
79
+ else
80
+ begin
81
+ content = Yajl::Parser.new.parse(response.body)
82
+ rescue Yajl::ParseError
83
+ raise DecodeError, "content: <#{response.body}>"
84
+ end
85
+ end
86
+
87
+ content
88
+ end
89
+
90
+ def build_query(data)
91
+ data = data.to_a if data.is_a?(Hash)
92
+ data.map do |key, value|
93
+ [key.to_s, URI.escape(value.to_s)].join('=')
94
+ end.join('&')
95
+ end
96
+
97
+ def send_request(method, endpoint, headers, data=nil)
98
+ begin
99
+ case method
100
+ when :get
101
+ response = RestClient.get endpoint, headers
102
+ when :delete
103
+ response = RestClient.delete endpoint, headers
104
+ when :post
105
+ response = RestClient.post endpoint, data, headers
106
+ when :put
107
+ response = RestClient.put endpoint, data, headers
108
+ end
109
+ rescue => e
110
+ raise_errors(e.response)
111
+ end
112
+
113
+ response
114
+ end
115
+
116
+ def raise_errors(response)
117
+ case response.code
118
+ when 401
119
+ raise Unauthorized
120
+ when 403
121
+ raise APIKeyExpired
122
+ when 404
123
+ raise NotFound
124
+ when 405
125
+ raise MethodNotAllowed
126
+ when 422
127
+ raise RestfulPressError, "#{response.description}\n#{response.body}"
128
+ when 500
129
+ raise ServerError, "RestfulPress had an internal error. #{response.description}"
130
+ when 502..503
131
+ raise Unavailable, response.description
132
+ else
133
+ raise RestfulPressError, response.description
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ end
@@ -0,0 +1,27 @@
1
+ module RestfulPress
2
+
3
+ class Endpoint
4
+
5
+ class << self
6
+
7
+ def job(id)
8
+ endpoint_url ["jobs", "#{id}.json"].join('/')
9
+ end
10
+
11
+ def jobs
12
+ endpoint_url "jobs.json"
13
+ end
14
+
15
+ def download_job(id)
16
+ endpoint_url ["jobs", id, "download"].join('/')
17
+ end
18
+
19
+ def endpoint_url(path)
20
+ [REALM, path].join('/')
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,28 @@
1
+ module RestfulPress
2
+
3
+ class HashUtils
4
+
5
+ def self.symbolize_keys(hash)
6
+ hash.inject({}) do |options, (key, value)|
7
+ options[(key.to_sym rescue key) || key] = value
8
+ options
9
+ end
10
+ end
11
+
12
+ def self.recursively_symbolize_keys(object)
13
+ if object.is_a? Hash
14
+ symbolized_hash = symbolize_keys(object)
15
+ symbolized_hash.each do |key, value|
16
+ symbolized_hash[key] = recursively_symbolize_keys(value)
17
+ end
18
+ symbolized_hash
19
+ elsif object.is_a? Array
20
+ object.map {|value| recursively_symbolize_keys(value) }
21
+ else
22
+ object
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,2 @@
1
+ # So you can require "restfulpress" instead of "restful_press"
2
+ require File.dirname(__FILE__) + '/restclient'
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "RestfulPress" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'restful_press'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: restful_press
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Mauricio Gomes
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-25 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: yajl-ruby
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 0
32
+ - 7
33
+ - 7
34
+ version: 0.7.7
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rest-client
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 6
49
+ - 0
50
+ version: 1.6.0
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 13
62
+ segments:
63
+ - 1
64
+ - 2
65
+ - 9
66
+ version: 1.2.9
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: "Restful Press is an automated service for converting your app's views into PDFs. "
70
+ email: mauricio@geminisbs.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - LICENSE
77
+ - README.rdoc
78
+ files:
79
+ - LICENSE
80
+ - README.rdoc
81
+ - VERSION
82
+ - lib/restful_press.rb
83
+ - lib/restful_press/client.rb
84
+ - lib/restful_press/connection.rb
85
+ - lib/restful_press/endpoint.rb
86
+ - lib/restful_press/hash_utils.rb
87
+ - lib/restfulpress.rb
88
+ - spec/restful_press_spec.rb
89
+ - spec/spec_helper.rb
90
+ has_rdoc: true
91
+ homepage: http://github.com/geminisbs/restful_press
92
+ licenses: []
93
+
94
+ post_install_message:
95
+ rdoc_options:
96
+ - --charset=UTF-8
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ requirements: []
118
+
119
+ rubyforge_project:
120
+ rubygems_version: 1.3.7
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Ruby client for the Restful Press API
124
+ test_files:
125
+ - spec/restful_press_spec.rb
126
+ - spec/spec_helper.rb