adobe_doc_api 0.1.3 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/Gemfile.lock +57 -0
- data/README.md +26 -15
- data/lib/adobe_doc_api/client.rb +64 -73
- data/lib/adobe_doc_api/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 561ccbe710cbc9856655dc3d4235846dc2c55bacbc6d44794cc76282846b87b1
|
4
|
+
data.tar.gz: 7df931d666bb7cd7007b7c870504b996a77103e80a09ba5e97c21e9b96f8e8c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc3925566f5027e07062cfd437d65898df2e688d33b39b6977bdf1d9954688e1d8677cb72d81b1ff4142082c022d258590166499380e37572af147da9c12cf85
|
7
|
+
data.tar.gz: 8500d15211572b7377e7e2710ca0d6c926555df58e3980972561f6b3843f483381d1d2fe70e69487c8f2edbe71a1953a8372b6f4eed38f872742871577dd9cb3
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
## [
|
1
|
+
## [0.2.1] - 2023-06-20
|
2
|
+
- Updates to Adobe PDF Services API
|
3
|
+
- Removed JWT token authentication
|
4
|
+
|
5
|
+
## [0.1.4] - 2021-12-30
|
6
|
+
- Fix issue with parsing file boundary that included \r\n
|
2
7
|
|
3
8
|
## [0.1.3] - 2021-12-30
|
4
9
|
- Added ability to configure AdobeDocApi to provide better customization
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
adobe_doc_api (0.2.0)
|
5
|
+
faraday (~> 1.8)
|
6
|
+
faraday_middleware (~> 1.2)
|
7
|
+
jwt (~> 2.3.0)
|
8
|
+
openssl (~> 2.2.1)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
faraday (1.10.3)
|
14
|
+
faraday-em_http (~> 1.0)
|
15
|
+
faraday-em_synchrony (~> 1.0)
|
16
|
+
faraday-excon (~> 1.1)
|
17
|
+
faraday-httpclient (~> 1.0)
|
18
|
+
faraday-multipart (~> 1.0)
|
19
|
+
faraday-net_http (~> 1.0)
|
20
|
+
faraday-net_http_persistent (~> 1.0)
|
21
|
+
faraday-patron (~> 1.0)
|
22
|
+
faraday-rack (~> 1.0)
|
23
|
+
faraday-retry (~> 1.0)
|
24
|
+
ruby2_keywords (>= 0.0.4)
|
25
|
+
faraday-em_http (1.0.0)
|
26
|
+
faraday-em_synchrony (1.0.0)
|
27
|
+
faraday-excon (1.1.0)
|
28
|
+
faraday-httpclient (1.0.1)
|
29
|
+
faraday-multipart (1.0.4)
|
30
|
+
multipart-post (~> 2)
|
31
|
+
faraday-net_http (1.0.1)
|
32
|
+
faraday-net_http_persistent (1.2.0)
|
33
|
+
faraday-patron (1.0.0)
|
34
|
+
faraday-rack (1.0.0)
|
35
|
+
faraday-retry (1.0.3)
|
36
|
+
faraday_middleware (1.2.0)
|
37
|
+
faraday (~> 1.0)
|
38
|
+
ipaddr (1.2.5)
|
39
|
+
jwt (2.3.0)
|
40
|
+
minitest (5.15.0)
|
41
|
+
multipart-post (2.3.0)
|
42
|
+
openssl (2.2.3)
|
43
|
+
ipaddr
|
44
|
+
rake (13.0.6)
|
45
|
+
ruby2_keywords (0.0.5)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
x86_64-darwin-19
|
49
|
+
x86_64-linux
|
50
|
+
|
51
|
+
DEPENDENCIES
|
52
|
+
adobe_doc_api!
|
53
|
+
minitest (~> 5.0)
|
54
|
+
rake (~> 13.0)
|
55
|
+
|
56
|
+
BUNDLED WITH
|
57
|
+
2.2.32
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# AdobeDocApi
|
2
2
|
|
3
|
-
This is still a work in progress
|
3
|
+
This is still a work in progress and breaking changes may be made, but I will do my best to update the README when features have been changed.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,35 +18,46 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install adobe_doc_api
|
20
20
|
|
21
|
-
## Configuration
|
22
|
-
* Configuration can be overridden if you need by passing the values to AdobeDocApi::Client.new
|
21
|
+
## Configuration
|
23
22
|
```ruby
|
24
23
|
AdobeDocApi.configure do |config|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
config.client_id = nil
|
25
|
+
config.client_secret = nil
|
26
|
+
config.org_id = nil
|
27
|
+
config.tech_account_id = nil
|
28
|
+
config.private_key_path = nil
|
29
|
+
end
|
30
|
+
```
|
31
|
+
### Recommended configuration if using Rails 6+
|
32
|
+
```ruby
|
33
|
+
AdobeDocApi.configure do |config|
|
34
|
+
config.client_id = Rails.application.credentials.dig(:adobe_doc, :client_id)
|
35
|
+
config.client_secret = Rails.application.credentials.dig(:adobe_doc, :client_secret)
|
36
|
+
config.org_id = Rails.application.credentials.dig(:adobe_doc, :org_id)
|
37
|
+
config.tech_account_id = Rails.application.credentials.dig(:adobe_doc, :tech_account_id)
|
38
|
+
config.private_key_path = Rails.application.credentials.dig(:adobe_doc, :private_key_path)
|
30
39
|
end
|
31
40
|
```
|
32
|
-
|
33
41
|
## Usage
|
34
42
|
|
35
43
|
```ruby
|
36
|
-
key_path = "../full_path_to/private.key"
|
37
44
|
template_path = "../full_path_to/disclosure.docx"
|
38
45
|
output_path = "../full_path_to_output/output.docx"
|
39
46
|
json_data = { 'DocTag': 'Value', 'DocTag2': 'Value2'}
|
40
47
|
|
41
48
|
client = AdobeDocApi::Client.new
|
42
|
-
|
43
|
-
# Without configuration you must pass these values
|
44
|
-
# client = AdobeDocApi::Client.new(private_key: key_path, client_id: ENV['adobe_client_id'], client_secret: ENV['adobe_client_secret']org_id: ENV['adobe_org_id'], tech_account_id: ENV['adobe_tech_account_id'], access_token: nil)
|
45
|
-
|
46
49
|
client.submit(json: json_data, template: template_path, output: output_path)
|
47
50
|
# returns true or false if file was saved to output_path
|
48
51
|
```
|
49
|
-
|
52
|
+
### Usage without configuration
|
53
|
+
```ruby
|
54
|
+
client = AdobeDocApi::Client.new(private_key: key_path,
|
55
|
+
client_id: adobe_client_id,
|
56
|
+
client_secret: adobe_client_secret,
|
57
|
+
org_id: adobe_org_id,
|
58
|
+
tech_account_id: adobe_tech_account_id,
|
59
|
+
access_token: nil)
|
60
|
+
```
|
50
61
|
## Todo
|
51
62
|
- [x] Add multipart parsing to improve saving the file from the response
|
52
63
|
- [ ] Add documentation
|
data/lib/adobe_doc_api/client.rb
CHANGED
@@ -24,78 +24,85 @@ module AdobeDocApi
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def get_access_token(private_key)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
27
|
+
# TODO: JWT token deprecated and will stop working Jan 1, 2024.
|
28
|
+
# jwt_payload = {
|
29
|
+
# "iss" => @org_id,
|
30
|
+
# "sub" => @tech_account_id,
|
31
|
+
# "https://ims-na1.adobelogin.com/s/ent_documentcloud_sdk" => true,
|
32
|
+
# "aud" => "https://ims-na1.adobelogin.com/c/#{@client_id}",
|
33
|
+
# "exp" => (Time.now.utc + 60).to_i
|
34
|
+
# }
|
35
|
+
#
|
36
|
+
# rsa_private = OpenSSL::PKey::RSA.new File.read(private_key)
|
37
|
+
#
|
38
|
+
# jwt_token = JWT.encode jwt_payload, rsa_private, "RS256"
|
39
|
+
#
|
39
40
|
connection = Faraday.new do |conn|
|
40
41
|
conn.response :json, content_type: "application/json"
|
41
42
|
end
|
42
|
-
response = connection.post JWT_URL do |req|
|
43
|
+
# response = connection.post JWT_URL do |req|
|
44
|
+
# req.params["client_id"] = @client_id
|
45
|
+
# req.params["client_secret"] = @client_secret
|
46
|
+
# req.params["jwt_token"] = jwt_token
|
47
|
+
# end
|
48
|
+
scopes = "openid, DCAPI, AdobeID"
|
49
|
+
|
50
|
+
response = connection.post "https://ims-na1.adobelogin.com/ims/token/v3" do |req|
|
43
51
|
req.params["client_id"] = @client_id
|
44
|
-
req.
|
45
|
-
req.params["jwt_token"] = jwt_token
|
52
|
+
req.body = "client_secret=#{@client_secret}&grant_type=client_credentials&scope=#{scopes}"
|
46
53
|
end
|
47
|
-
|
48
54
|
return response.body["access_token"]
|
49
55
|
end
|
50
56
|
|
57
|
+
def get_asset_id
|
58
|
+
# Create new asset ID to get upload pre-signed Uri
|
59
|
+
connection = Faraday.new do |conn|
|
60
|
+
conn.request :authorization, "Bearer", @access_token
|
61
|
+
conn.headers["x-api-key"] = @client_id
|
62
|
+
conn.headers["Content-Type"] = ""
|
63
|
+
conn.response :json, content_type: "application/json"
|
64
|
+
end
|
65
|
+
response = connection.post "https://pdf-services.adobe.io/assets" do |req|
|
66
|
+
req.body = {mediaType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}.to_json
|
67
|
+
req.headers["Content-Type"] = "application/json"
|
68
|
+
end
|
69
|
+
# Return pre-signed uploadUri and assedID
|
70
|
+
return response.body["assetID"], response.body["uploadUri"]
|
71
|
+
end
|
72
|
+
|
51
73
|
def submit(json:, template:, output:)
|
52
|
-
|
53
|
-
output_format = /docx/.match?(File.extname(@output)) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/pdf"
|
74
|
+
asset_id, upload_uri = get_asset_id
|
54
75
|
|
76
|
+
# Upload template to asset created earlier.
|
77
|
+
response = Faraday.put upload_uri do |req|
|
78
|
+
req.headers["Content-Type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
79
|
+
req.body = File.binread(template)
|
80
|
+
end
|
81
|
+
raise("Failed to upload template.") if response.status.to_i != 200
|
82
|
+
|
83
|
+
# Post JSON Data for Merge to documentGeneration
|
55
84
|
content_request = {
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
"cpf:inputs": {
|
60
|
-
documentIn: {
|
61
|
-
"dc:format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
62
|
-
"cpf:location": "InputFile0"
|
63
|
-
},
|
64
|
-
params: {
|
65
|
-
"cpf:inline": {
|
66
|
-
outputFormat: File.extname(@output).delete("."),
|
67
|
-
jsonDataForMerge: json
|
68
|
-
}
|
69
|
-
}
|
70
|
-
},
|
71
|
-
"cpf:outputs": {
|
72
|
-
documentOut: {
|
73
|
-
"dc:format": output_format.to_s,
|
74
|
-
"cpf:location": "multipartLabel"
|
75
|
-
}
|
76
|
-
}
|
85
|
+
assetID: asset_id,
|
86
|
+
outputFormat: File.extname(output).delete("."),
|
87
|
+
jsonDataForMerge: json
|
77
88
|
}.to_json
|
78
|
-
|
79
|
-
connection = Faraday.new
|
89
|
+
payload = content_request
|
90
|
+
connection = Faraday.new do |conn|
|
80
91
|
conn.request :authorization, "Bearer", @access_token
|
81
92
|
conn.headers["x-api-key"] = @client_id
|
82
|
-
conn.request :multipart
|
83
|
-
conn.request :url_encoded
|
84
|
-
conn.response :json, content_type: "application/json"
|
85
93
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
poll_for_file(@location_url)
|
94
|
+
res = connection.post "https://pdf-services-ue1.adobe.io/operation/documentgeneration" do |req|
|
95
|
+
req.body = payload
|
96
|
+
req.headers["Content-Type"] = "application/json"
|
97
|
+
end
|
98
|
+
# TODO need to check status of response
|
99
|
+
# Begin polling for status of file
|
100
|
+
poll_for_file(res.headers["location"], output)
|
94
101
|
end
|
95
102
|
|
96
103
|
private
|
97
104
|
|
98
|
-
def poll_for_file(url)
|
105
|
+
def poll_for_file(url, output)
|
99
106
|
connection = Faraday.new do |conn|
|
100
107
|
conn.request :authorization, "Bearer", @access_token
|
101
108
|
conn.headers["x-api-key"] = @client_id
|
@@ -105,11 +112,11 @@ module AdobeDocApi
|
|
105
112
|
sleep(6)
|
106
113
|
response = connection.get(url)
|
107
114
|
counter += 1
|
108
|
-
if response.body
|
109
|
-
|
110
|
-
return
|
115
|
+
if JSON.parse(response.body)["status"] == "done"
|
116
|
+
file_response = Faraday.get JSON.parse(response.body)["asset"]["downloadUri"]
|
117
|
+
return true if File.open(output, "wb") { |f| f.write file_response.body}
|
111
118
|
else
|
112
|
-
status = JSON.parse(response.body)["
|
119
|
+
status = JSON.parse(response.body)["status"]
|
113
120
|
raise Error.new(status_code: status["status"], msg: status) if status["status"] != 202
|
114
121
|
end
|
115
122
|
break if counter > 10
|
@@ -119,21 +126,5 @@ module AdobeDocApi
|
|
119
126
|
end
|
120
127
|
end
|
121
128
|
|
122
|
-
def write_to_file(response_body)
|
123
|
-
line_index = []
|
124
|
-
lines = response_body.split("\r\n")
|
125
|
-
lines.each_with_index do |line, i|
|
126
|
-
next if line.include?("--Boundary_") || line.match?(/^Content-(Type|Disposition):/) || line.empty? || JSON.parse(line.force_encoding("UTF-8").to_s)
|
127
|
-
rescue
|
128
|
-
line_index << i
|
129
|
-
end
|
130
|
-
if line_index.length == 1
|
131
|
-
File.open(@output, "wb") { |f| f.write lines.at(line_index[0])}
|
132
|
-
true
|
133
|
-
else
|
134
|
-
false
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
129
|
end
|
139
130
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adobe_doc_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Sonnier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- CHANGELOG.md
|
77
77
|
- CODE_OF_CONDUCT.md
|
78
78
|
- Gemfile
|
79
|
+
- Gemfile.lock
|
79
80
|
- LICENSE.txt
|
80
81
|
- README.md
|
81
82
|
- Rakefile
|