Skip to content

Commit 38ffdbb

Browse files
authored
Merge pull request #7 from ARPC/document-merge-new-api
Document merge new api
2 parents df6d0d7 + 78f5e2f commit 38ffdbb

11 files changed

Lines changed: 157 additions & 105 deletions

File tree

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
pdfservices (0.1.2)
4+
pdfservices (0.1.3)
55
http (~> 5.1)
66
json (~> 2.6)
77
jwt (>= 1.0, < 3.0)
@@ -31,7 +31,7 @@ GEM
3131
domain_name (~> 0.5)
3232
http-form_data (2.3.0)
3333
json (2.6.2)
34-
jwt (2.6.0)
34+
jwt (2.7.0)
3535
llhttp-ffi (0.4.0)
3636
ffi-compiler (~> 1.0)
3737
rake (~> 13.0)

lib/pdfservices/document_merge/operation.rb

Lines changed: 71 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
module PdfServices
99
module DocumentMerge
1010
class Operation
11-
ENDPOINT = "https://cpf-ue1.adobe.io/ops/:create?respondWith=%7B%22reltype%22%3A%20%22http%3A%2F%2Fns.adobe.com%2Frel%2Fprimary%22%7D"
12-
DOCUMENT_GENERATION_ASSET_ID = "urn:aaid:cpf:Service-52d5db6097ed436ebb96f13a4c7bf8fb"
11+
PRESIGNED_URL_ENDPOINT = "https://pdf-services.adobe.io/assets"
12+
OPERATION_ENDPOINT = "https://pdf-services.adobe.io/operation/documentgeneration"
13+
ASSETS_ENDPOINT = "https://pdf-services.adobe.io/assets"
1314

1415
def initialize(credentials = nil, template_path = nil, json_data_for_merge = nil, output_format = nil)
1516
@credentials = credentials
@@ -18,85 +19,92 @@ def initialize(credentials = nil, template_path = nil, json_data_for_merge = nil
1819
@output_format = output_format
1920
end
2021

21-
def execute
22-
form = {
23-
contentAnalyzerRequests: build_content_analyzer_requests.to_json,
24-
InputFile0: build_input_file
25-
}
26-
response = api.post(ENDPOINT, form: form)
27-
if response.status == 202
28-
document_url = response.headers["Location"]
29-
poll_document_result(document_url)
22+
def get_presigned_url
23+
response = api.post(PRESIGNED_URL_ENDPOINT, json: {mediaType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"})
24+
if response.status == 200
25+
JSON.parse(response.body.to_s)
3026
else
31-
Result.new(nil, "Unexpected response status: #{response.status}")
27+
Result.new(nil, "Unexpected response status from get presigned url: #{response.status}")
3228
end
3329
end
3430

35-
private
31+
def upload_asset(template_path)
32+
presigned_url = get_presigned_url
33+
upload_uri = presigned_url["uploadUri"]
34+
asset_id = presigned_url["assetID"]
35+
aws = HTTP.headers({"Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"})
36+
response = aws.put(upload_uri, body: File.open(template_path))
37+
if response.status == 200
38+
asset_id
39+
else
40+
Result.new(nil, "Unexpected response status from asset upload: #{response.status}")
41+
end
42+
end
3643

37-
def build_content_analyzer_requests
38-
{
39-
"cpf:engine": {
40-
"repo:assetId": DOCUMENT_GENERATION_ASSET_ID
41-
},
42-
"cpf:inputs": {
43-
documentIn: {
44-
"dc:format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
45-
"cpf:location": "InputFile0"
46-
},
47-
params: {
48-
"cpf:inline": {
49-
outputFormat: @output_format,
50-
jsonDataForMerge: @json_data_for_merge
51-
}
52-
}
53-
},
54-
"cpf:outputs": {
55-
documentOut: {
56-
"dc:format": mime_type(@output_format),
57-
"cpf:location": "multipartLabel"
58-
}
59-
}
60-
}
44+
def delete_the_asset(asset_id)
45+
api.delete("#{ASSETS_ENDPOINT}/#{asset_id}")
6146
end
6247

63-
def build_headers
48+
def execute
49+
asset_id = upload_asset(@template_path)
50+
response = api.post(OPERATION_ENDPOINT, json: {
51+
assetID: asset_id,
52+
outputFormat: @output_format,
53+
jsonDataForMerge: @json_data_for_merge
54+
})
55+
if response.status == 201
56+
document_url = response.headers["location"]
57+
poll_document_result(document_url, asset_id)
58+
else
59+
Result.new(nil, "Unexpected response status from document merge endpoint: #{response.status}\nasset_id: #{asset_id}")
60+
end
61+
end
62+
63+
private
64+
65+
def api_headers
6466
{
6567
Authorization: "Bearer #{JwtProvider.get_jwt(@credentials)}",
6668
"x-api-key": @credentials.client_id,
67-
Prefer: "respond-async,wait=0"
69+
"Content-Type": "application/json"
6870
}
6971
end
7072

71-
def build_input_file
72-
HTTP::FormData::File.new(@template_path)
73-
end
74-
7573
def api
76-
@api ||= HTTP.headers(build_headers)
74+
@api ||= HTTP.headers(api_headers)
7775
end
7876

79-
def poll_document_result(url)
77+
def poll_document_result(url, original_asset_id)
8078
sleep(1)
81-
document_response = api.get(url)
82-
case document_response.content_type.mime_type
83-
when "application/json"
84-
poll_document_result(url)
85-
when "multipart/mixed"
86-
Result.from_multipart_response(document_response)
87-
else
88-
Result.new(nil, "Unexpected response content type: #{document_response.content_type.mime_type}; status: #{document_response.status}")
89-
end
90-
end
91-
92-
def mime_type(format)
93-
case format
94-
when :docx
95-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
96-
when :pdf
97-
"application/pdf"
79+
response = api.get(url)
80+
if response.status == 200
81+
json_response = JSON.parse(response.body.to_s)
82+
document_merge_asset_id = json_response&.[]("asset")&.[]("assetID")
83+
case json_response["status"]
84+
when "in progress"
85+
poll_document_result(url, original_asset_id)
86+
when "done"
87+
# download_the_asset
88+
response = HTTP.get(json_response["asset"]["downloadUri"])
89+
# delete the assets
90+
delete_the_asset(original_asset_id) if !original_asset_id.nil?
91+
delete_the_asset(document_merge_asset_id) if !document_merge_asset_id.nil?
92+
# return the result
93+
Result.new(response.body, nil)
94+
when "failed"
95+
# delete the original asset
96+
message = json_response["error"]["message"]
97+
delete_the_asset(original_asset_id) if !original_asset_id.nil?
98+
Result.new(nil, message)
99+
else
100+
# delete the original asset
101+
delete_the_asset(original_asset_id) if original_asset_id.present?
102+
Result.new(nil, "Unexpected status from polling: #{json_response["status"]}")
103+
end
98104
else
99-
"text/plain"
105+
# delete the original asset
106+
delete_the_asset(original_asset_id) if original_asset_id.present?
107+
Result.new(nil, "Unexpected response status from polling: #{json_response["status"]}")
100108
end
101109
end
102110
end

lib/pdfservices/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module PdfServices
4-
VERSION = "0.1.2"
4+
VERSION = "0.1.3"
55
end

test/fixtures/files/merge_done.pdf

24.5 KB
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"status": "done",
3+
"asset": {
4+
"assetID": "merged:asset-id",
5+
"downloadUri": "https://documentmerge.file.url"
6+
}
7+
}
Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,3 @@
11
{
2-
"cpf:status": {
3-
"completed": false,
4-
"type": "",
5-
"title": "In Progress",
6-
"status": 202
7-
},
8-
"cpf:engine": {
9-
"repo:assetId": "urn:aaid:cpf:Service-52d5db6097ed436ebb96f13a4c7bf8fb"
10-
},
11-
"cpf:inputs": {
12-
"documentIn": {
13-
"dc:format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
14-
"cpf:location": "InputFile0"
15-
},
16-
"params": {
17-
"cpf:inline": {
18-
"outputFormat": "pdf",
19-
"jsonDataForMerge": {
20-
"message": "World"
21-
}
22-
}
23-
}
24-
}
2+
"status": "in progress"
253
}
-53.4 KB
Binary file not shown.

test/fixtures/ocr_done.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
{
2-
"status": "in progress"
2+
"status": "done",
3+
"asset": {
4+
"assetID": "ocr'd:asset-id",
5+
"downloadUri": "https://ocr.file.url"
6+
}
37
}

test/fixtures/ocr_in_progress.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
{
2-
"status": "done",
3-
"asset": {
4-
"assetID": "ocr'd:asset-id",
5-
"downloadUri": "https://ocr.file.url"
6-
}
2+
"status": "in progress"
73
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
require "lib/pdfservices"
4+
5+
credentials = ::PdfServices::CredentialsBuilder.new
6+
.with_client_id(ENV["PDF_SERVICES_CLIENT_ID"])
7+
.with_client_secret(ENV["PDF_SERVICES_CLIENT_SECRET"])
8+
.with_organization_id(ENV["PDF_SERVICES_ORGANIZATION_ID"])
9+
.with_account_id(ENV["PDF_SERVICES_ACCOUNT_ID"])
10+
.with_private_key(ENV["PDF_SERVICES_PRIVATE_KEY"])
11+
.build
12+
13+
json = {message: "World"}
14+
word_file = File.join(Dir.pwd, "test", "fixtures", "files", "sample_template.docx")
15+
operation = ::PdfServices::DocumentMerge::Operation.new(credentials, word_file, json, "pdf")
16+
17+
result = operation.execute
18+
19+
puts(result.error)
20+
21+
result.save_as_file("tmp/document_merge_result.pdf")

0 commit comments

Comments
 (0)