restful_press 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/LICENSE +20 -0
- data/README.rdoc +71 -0
- data/VERSION +1 -0
- data/lib/restful_press.rb +23 -0
- data/lib/restful_press/client.rb +100 -0
- data/lib/restful_press/connection.rb +139 -0
- data/lib/restful_press/endpoint.rb +27 -0
- data/lib/restful_press/hash_utils.rb +28 -0
- data/lib/restfulpress.rb +2 -0
- data/spec/restful_press_spec.rb +7 -0
- data/spec/spec_helper.rb +9 -0
- metadata +126 -0
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.
|
data/README.rdoc
ADDED
@@ -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
|
data/lib/restfulpress.rb
ADDED
data/spec/spec_helper.rb
ADDED
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
|