easy_pdf_cloud 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MWM2NDlmYWQ3YzcwYWQwYmFhMDE4NmQ5NmRiNzI5NjA2MWEzOWZhNg==
5
+ data.tar.gz: !binary |-
6
+ Y2JmOTQxMTliYWI3YzdhN2Y2ZjMyMzYwMjhkODk0OTlhYmU4MjA5ZQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjQ4OGFiZGJkOWVhN2NkZDkzOTVhMjFhMmM4OWY2NDQyNzRkMjg3MmVlZDdl
10
+ ZWQ2OGM0ZDhmNjY0NjRjNTdiYWYxZjVkMTY4Y2RjN2YxZDAwOGU5NWMyZTE0
11
+ N2NjNDkxOWMyNzRiNzFhNTJmZjcxMmY0MDM1ZDU5ODFhMzA3OTI=
12
+ data.tar.gz: !binary |-
13
+ ZjYzZDQyOThjMjMwN2EwMjdmNTU5MDJjZDYyNjQxMjI4NjRjMzVkOThmOGUw
14
+ NTljOWNmZDhiMjBiNDhkYzIyYzEyNjZmMjdjYTc3YzQ3OWViNmE1MmEyOWVj
15
+ N2Q5YWFiYzA3NGViMjAwNmUzNjU5MTYwNzk5YzZmN2Y0YzZhZTI=
@@ -0,0 +1,18 @@
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
18
+ vendor
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pdf_cloud.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Joe Heth
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.
@@ -0,0 +1,65 @@
1
+ # EasyPDFCloud
2
+
3
+ [easypdfcloud.com](https://www.easypdfcloud.com/) provides a RESTful API for accessing
4
+
5
+ This branch supports version 1 of api.easypdfcloud.com.
6
+
7
+ [Developer API Reference](https://www.easypdfcloud.com/developer/reference)
8
+
9
+ This gem assumes you've gone through the OAuth process and have a refresh token.
10
+ The easypdfcloud.com access token expires in an hour so this gem requires a refresh token to be configured
11
+ so it can automatically refresh when needed.
12
+
13
+ Configuration:
14
+
15
+ client_id: '...'
16
+ client_secret: '...'
17
+ workflow_id: '0000000000000001'
18
+ refresh_token: '...'
19
+ version: 'v1'
20
+
21
+ Usage:
22
+
23
+ pdf_cloud_config = YAML.load_file(File.join(Rails.root, "config", "easypdfcloud.yml"))
24
+ pdf_cloud = EasyPdfCloud::Client.new(pdf_cloud_config)
25
+
26
+ # Local File System conversion. Uses configured workflow id.
27
+ out_filepath = pdf_cloud.convert("/path/to/filename.pdf", 'pdf', 'doc')
28
+ # Optionally pass a workflow id
29
+ out_filepath = pdf_cloud.convert("/path/to/filename.pdf", 'pdf', 'doc', workflow_id)
30
+
31
+ # Raw Data transform
32
+ pdf_data = File.open("somefile.pdf") { |f| f.read }
33
+ # This method uses the configured workflow id.
34
+ doc_data = pdf_cloud.pdf2word("#{Time.now.to_i}.pdf", pdf_data)
35
+ File.open('test.doc', 'wb') {|f| f.write(doc_data)}
36
+
37
+ ## Installation
38
+
39
+ Add this line to your application's Gemfile:
40
+
41
+ gem 'easy_pdf_cloud'
42
+
43
+ And then execute:
44
+
45
+ $ bundle
46
+
47
+ Or install it yourself as:
48
+
49
+ $ gem install easy_pdf_cloud
50
+
51
+ ## Usage
52
+
53
+ ~~~
54
+ client = EasyPdfCloud::Client.new(client_id, client_secret, access_token)
55
+ puts client.workflows
56
+ client.workflow(workflow_id).convert(filename, 'pdf', 'doc')
57
+ ~~~
58
+
59
+ ## Contributing
60
+
61
+ 1. Fork it
62
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
63
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
64
+ 4. Push to the branch (`git push origin my-new-feature`)
65
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'easy_pdf_cloud/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "easy_pdf_cloud"
8
+ gem.version = EasyPdfCloud::VERSION
9
+ gem.authors = ["Joe Heth"]
10
+ gem.email = ["joeheth@gmail.com"]
11
+ gem.description = %q{Simplified access to the easypdfcloud.com RESTful API}
12
+ gem.summary = %q{Document conversion using easypdfcloud.com}
13
+ gem.homepage = "https://github.com/TinderBox/easy_pdf_cloud"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_runtime_dependency "oauth2", "~> 0.9"
22
+ end
@@ -0,0 +1,214 @@
1
+ require "easy_pdf_cloud/version"
2
+ require 'oauth2'
3
+
4
+ module EasyPdfCloud
5
+
6
+ class Client
7
+
8
+ # The client id (aka "Consumer Key") to use for OAuth2 authentication
9
+ attr_accessor :client_id
10
+ # The client secret (aka "Consumer Secret" to use for OAuth2 authentication)
11
+ attr_accessor :client_secret
12
+ # The OAuth access token in use by the client
13
+ attr_accessor :access_token
14
+ # The OAuth refresh token in use by the client
15
+ attr_accessor :refresh_token
16
+ # The host to use for OAuth2 authentication. Defaults to www.easypdfcloud.com
17
+ attr_accessor :host
18
+ # The host to use for API requests. Defaults to api.easypdfcloud.com
19
+ attr_accessor :api_host
20
+ # The API version the client is using. Defaults to v1
21
+ attr_accessor :version
22
+ # The base URL to the workflow API
23
+ attr_reader :workflow_url
24
+ # The base URL to the Base API https://{api_host}/{version}
25
+ attr_reader :api_url
26
+
27
+ def initialize(options)
28
+
29
+ @options = options
30
+ @host = options['host'] || 'https://www.easypdfcloud.com'
31
+ @api_host = options['api_host'] || "https://api.easypdfcloud.com"
32
+ @version = options['version'] || "v1"
33
+ @api_url = "#{@api_host}/#{@version}"
34
+ @workflow_url = "#{@api_url}/workflows"
35
+ @client_id = options['client_id']
36
+ @client_secret = options['client_secret']
37
+ @access_token = options['access_token']
38
+ @refresh_token = options['refresh_token']
39
+
40
+ client_options = {
41
+ :site => @host,
42
+ :authorize_url => '/oauth2/authorize',
43
+ :token_url => '/oauth2/token'
44
+ }
45
+ @client = OAuth2::Client.new(@client_id, @client_secret, client_options)
46
+ #@client.auth_code.authorize_url(:redirect_uri => 'http://localhost', :scope => "epc.api", :state => "EasyPDFCloud")
47
+
48
+ @access_token = OAuth2::AccessToken.from_hash(@client, {:access_token => @access_token, :refresh_token => @refresh_token})
49
+ end
50
+
51
+ def verify_access_token
52
+ begin
53
+ workflows()
54
+ rescue => e
55
+ puts e.message
56
+ raise "Access denied to easypdfcloud.com API. Verify your access and/or refresh token."
57
+ end
58
+ end
59
+
60
+ def check_access_token
61
+ if @access_token.expired? || @access_token.token.empty?
62
+ puts "Refreshing EasyPdfCloud Access Token"
63
+ # For older versions of oauth2 the refresh_token is not properly carried over after the call to refresh!
64
+ @access_token = OAuth2::AccessToken.from_hash(@client, {:access_token => @options["access_token"], :refresh_token => @options["refresh_token"]})
65
+ @access_token = @access_token.refresh!
66
+ verify_access_token
67
+ end
68
+ end
69
+
70
+ def convert(filename, input_type, output_type, workflow_id=nil)
71
+ check_access_token
72
+ out_filepath = nil
73
+ wid = workflow_id || @options["workflow_id"]
74
+ if wid
75
+ out_filepath = workflow(wid).convert(filename, input_type, output_type)
76
+ else
77
+ raise "No workflow id was specified"
78
+ end
79
+ return out_filepath
80
+ end
81
+
82
+ def pdf2word(filename, pdf_data, workflow_id=nil)
83
+ check_access_token
84
+ word_data = ""
85
+ if @options.has_key?("workflow_id") || workflow_id
86
+ id = (workflow_id ? workflow_id : @options["workflow_id"])
87
+ word_data = workflow(id).convert_data(filename, pdf_data, 'pdf', 'doc')
88
+ else
89
+ raise "No workflow id was specified"
90
+ end
91
+ return word_data
92
+ end
93
+
94
+ def workflows
95
+ check_access_token
96
+ response = @access_token.get(@workflow_url)
97
+ hash = response.parsed
98
+ hash["workflows"]
99
+ end
100
+
101
+ def workflow_details(id)
102
+ response = @access_token.get("#{@workflow_url}/#{id}")
103
+ workflow_id = response.parsed["workflowID"].to_i
104
+ Workflow.new(self, workflow_id)
105
+ end
106
+
107
+ def workflow(id)
108
+ Workflow.new(self, id)
109
+ end
110
+
111
+ end
112
+
113
+ class Workflow
114
+ def initialize(client, workflow_id, options = {})
115
+ @client = client
116
+ @access_token = client.access_token
117
+ @workflow_id = workflow_id
118
+ @workflow_url = "#{client.workflow_url}/#{@workflow_id}"
119
+ @jobs_url = "#{client.api_url}/jobs"
120
+ @event_id = nil
121
+ @debug = options[:debug]
122
+ end
123
+
124
+ def convert(filepath, source_extension, dest_extension)
125
+ raise "Invalid file: #{filepath}" if !File.file?(filepath)
126
+
127
+ file_data = File.open(filepath, 'rb') {|f| f.read}
128
+ filename = File.basename(filepath)
129
+
130
+ out_data = convert_data(filename, file_data, source_extension, dest_extension)
131
+
132
+ out_filepath = filepath.sub(".#{source_extension}", ".#{dest_extension}")
133
+ File.open(out_filepath, "wb") {|f| f.write(out_data)}
134
+ return out_filepath
135
+ end
136
+
137
+ def convert_data(filename, data, source_extension, dest_extension)
138
+ job_id = create_job_from_file(filename, data)
139
+ wait_for_completion(job_id)
140
+ output_file = filename.sub(".#{source_extension}", ".#{dest_extension}")
141
+ response = retrieve_file(job_id, output_file)
142
+ # The job stays around after execution. We can either delete or keep a history some where.
143
+ # delete_job(job_id)
144
+ # Delete the output file so it doesn't take up storage space.
145
+ delete_output_file(job_id, output_file)
146
+ response.body
147
+ end
148
+
149
+ def create_job_from_file(filename, file_data)
150
+ create_job_url = "#{@workflow_url}/jobs?file=#{filename}"
151
+ response = @access_token.put(create_job_url, {:body => file_data, :headers => {"Content-Type" => "application/pdf"}})
152
+ return response.parsed["jobID"]
153
+ end
154
+
155
+ # Download Output File
156
+ def download(job_id, filename, destination_path = nil)
157
+ response = retrieve_file(job_id, filename)
158
+ filepath = (destination_path ? File.join(destination_path, filename) : filename)
159
+
160
+ File.open(filepath, "wb") {|f| f.write(response.body)}
161
+ delete_output_file(job_id, filename)
162
+ true
163
+ end
164
+
165
+ def retrieve_file(job_id, filename)
166
+ file_url = "#{@jobs_url}/#{job_id}/output/#{filename}"
167
+ response = @access_token.get(file_url)
168
+ end
169
+
170
+ # Delete File from output folder.
171
+ def delete_output_file(job_id, filename)
172
+ file_url = "#{@jobs_url}/#{job_id}/output/#{filename}"
173
+ response = @access_token.delete(file_url)
174
+ return response.parsed.is_a?(Hash)
175
+ end
176
+
177
+ # There is no response from this command.
178
+ def start_job(id)
179
+ response = @access_token.post("#{@jobs_url}/#{id}")
180
+ response.status
181
+ end
182
+
183
+ def delete_job(id)
184
+ response = @access_token.delete("#{@jobs_url}/#{id}")
185
+ response.status
186
+ end
187
+
188
+ def wait_for_completion(job_id)
189
+ count = 0
190
+ while (job_event(job_id) == false)
191
+ if count == 6
192
+ delete_job(job_id)
193
+ raise "Failed to convert after 180 seconds."
194
+ end
195
+ count += 1
196
+ end
197
+ end
198
+
199
+ def job_status(job_id)
200
+ response = @access_token.get("#{@jobs_url}/#{job_id}")
201
+ response.parsed
202
+ end
203
+
204
+ # https://www.easypdfcloud.com/developer/reference#jobs_event
205
+ # This API waits for an event for up to 30 seconds.
206
+ # If the job execution does not complete within this duration, returns HTTP status code 202 (Accepted).
207
+ def job_event(job_id)
208
+ response = @access_token.post("#{@jobs_url}/#{job_id}/event")
209
+ hash = response.parsed
210
+ return hash["status"] == "completed"
211
+ end
212
+ end
213
+
214
+ end
@@ -0,0 +1,3 @@
1
+ module EasyPdfCloud
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easy_pdf_cloud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Joe Heth
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oauth2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ description: Simplified access to the easypdfcloud.com RESTful API
28
+ email:
29
+ - joeheth@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - Gemfile
36
+ - LICENSE.txt
37
+ - README.md
38
+ - Rakefile
39
+ - easy_pdf_cloud.gemspec
40
+ - lib/easy_pdf_cloud.rb
41
+ - lib/easy_pdf_cloud/version.rb
42
+ homepage: https://github.com/TinderBox/easy_pdf_cloud
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.2.2
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Document conversion using easypdfcloud.com
66
+ test_files: []