Skip to content

Commit

Permalink
Merge pull request #16 from ilovepdf/feature/signature/add-signature-…
Browse files Browse the repository at this point in the history
…form-methods

Updated signature tool with PDF Forms
  • Loading branch information
guillem-pdf authored Oct 9, 2024
2 parents af4cc4a + 5d00bb3 commit 8c16c71
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 16 deletions.
3 changes: 3 additions & 0 deletions lib/ilovepdf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
require "ilovepdf/task"
require 'ilovepdf/element'
require 'ilovepdf/request_payload/form_url_encoded'
require 'ilovepdf/extra_upload_params/base'
require 'ilovepdf/extra_upload_params/signature'
require 'ilovepdf/pdf_page'

# Load tool classes
require 'ilovepdf/tool/compress'
Expand Down
17 changes: 17 additions & 0 deletions lib/ilovepdf/extra_upload_params/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Ilovepdf
module ExtraUploadParams
class Base
attr_accessor :extra_params

def set_value(key,value)
self.extra_params||= {}
self.extra_params[key] = value
end

def get_values()
self.extra_params
end

end
end
end
23 changes: 23 additions & 0 deletions lib/ilovepdf/extra_upload_params/signature.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'ilovepdf/extra_upload_params/base'
module Ilovepdf
module ExtraUploadParams

class Signature < Base

def set_pdf_info(activate = true)
self.set_value(:pdfinfo,!!activate ? "1" : "0")
self
end

def set_pdf_forms(activate = true)
is_active = !!activate
self.set_value(:pdfforms,is_active ? "1" : "0")
if is_active
self.set_pdf_info(true)
end
self
end
end

end
end
21 changes: 20 additions & 1 deletion lib/ilovepdf/file.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Ilovepdf
class File
attr_accessor :server_filename, :filename, :password, :info
attr_accessor :server_filename, :filename, :password, :info, :pdf_pages, :pdf_forms, :pdf_page_number
attr_reader :rotate

ROTATION_VALUES = [0, 90, 180, 270]
Expand All @@ -21,6 +21,25 @@ def file_options
h
end

# pageNumber is an integer and it must be greater than 1 (1 is the first page)
def pdf_page_info(pageNumber)
pdf_page_string = self.pdf_pages.at(pageNumber-1)
width,height = 0.0
return nil if !pdf_page_string.is_a?(String)
PdfPage.initialize_from_string(pdf_page_string)
end

def last_pdf_page
self.pdf_pages
end

def each_pdf_form_element
self.pdf_forms&.each do |pdf_form_element|
pdf_page = self.pdf_page_info(pdf_form_element['page'])
yield(pdf_form_element,pdf_page)
end
end

def rotate= degrees
raise Errors::ArgumentEnumError.new(ROTATION_VALUES) unless ROTATION_VALUES.include? degrees
@rotate = degrees
Expand Down
15 changes: 15 additions & 0 deletions lib/ilovepdf/pdf_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Ilovepdf
class PdfPage
attr_accessor :width,:height

def initialize(width, height)
self.width = width
self.height = height
end

def self.initialize_from_string(string)
width, height = string.split("x").map(&:to_f)
PdfPage.new(width, height)
end
end
end
43 changes: 33 additions & 10 deletions lib/ilovepdf/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ def files
@files ||= []
end

def add_file(filepath)
def add_file(filepath, extra_upload_params = nil)
raise ArgumentError.new("No file exists in '#{filepath}'") unless ::File.exist?(filepath)
file = perform_upload_request(filepath)
file = perform_upload_request(filepath,extra_upload_params)
files << file
files.last
file
end

def add_file_from_url(url)
file = perform_upload_url_request(url)
def add_file_from_url(url,extra_upload_params = nil)
file = perform_upload_url_request(url,extra_upload_params)
files << file
files.last
file
end

def download(path=nil, create_directory: false)
Expand Down Expand Up @@ -209,7 +209,7 @@ def perform_start_request
response
end

def perform_upload_request filepath
def perform_upload_request filepath, tool_additional_params = nil
request_opts = {
body: {
multipart: true,
Expand All @@ -218,12 +218,16 @@ def perform_upload_request filepath
file: ::File.new(filepath, 'rb')
}
}
if tool_additional_params.is_a?(::Ilovepdf::ExtraUploadParams::Base)
request_opts[:body].merge!(tool_additional_params.extra_params.transform_keys(&:to_sym))
end

# filepath
response = send_request('post', 'upload', request_opts)
File.new(response.body['server_filename'], Pathname.new(filepath).basename.to_s)
self.get_file_from_response(response.body,filepath)
end

def perform_upload_url_request url
def perform_upload_url_request url,tool_additional_params = nil
request_opts = {
body: {
multipart: true,
Expand All @@ -232,8 +236,11 @@ def perform_upload_url_request url
cloud_file: url
}
}
if tool_additional_params.is_a?(::Ilovepdf::ExtraUploadParams::Base)
request_opts[:body].merge!(tool_additional_params.extra_params.transform_keys(&:to_sym))
end
response = send_request('post', 'upload', request_opts)
File.new(response.body['server_filename'], Pathname.new(url).basename.to_s)
self.get_file_from_response(response.body,url)
end

def file_submit_params
Expand All @@ -254,5 +261,21 @@ def extract_api_params
result
end
end

private

def get_file_from_response(response_body,filePathOrUrl)
file = File.new(response_body['server_filename'], Pathname.new(filePathOrUrl).basename.to_s)
if response_body['pdf_pages']
file.pdf_pages = response_body['pdf_pages']
end
if response_body['pdf_page_number']
file.pdf_page_number = response_body['pdf_page_number'].to_i
end
if response_body['pdf_forms']
file.pdf_forms = response_body['pdf_forms']
end
file
end
end
end
10 changes: 8 additions & 2 deletions lib/ilovepdf/tool/signature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,16 @@ def reminders=(value)
value
end

def upload_brand_logo_file(logoPath)
perform_upload_request(logoPath)
end

def upload_brand_logo_file_from_url(logoUrl)
perform_upload_url_request(logoUrl)
end

def add_brand(name:,logo:)
brand_logo_file = perform_upload_request(logo)
@brand_logo = brand_logo_file.server_filename
@brand_logo = logo.server_filename
@brand_name = name
end

Expand Down
2 changes: 1 addition & 1 deletion lib/ilovepdf/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Ilovepdf
VERSION = "1.3.4"
VERSION = "1.4.0"
end
5 changes: 3 additions & 2 deletions samples/signature_advanced.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
priv_key = "YOUR_PRIVATE_KEY"

my_task = Ilovepdf::Tool::Signature.new(pub_key, priv_key)
my_task.add_brand(name: "my company name",logo: "/path/to/logo/logo.png")
# Upload brand logo
brand_logo = my_task.upload_brand_logo_file("/path/to/logo/logo.png")
my_task.add_brand(name: "my company name",logo: brand_logo)
my_task.language = "es"
my_task.lock_order = false # if false, allows receivers of signer type to sign in parallel.
# if true receivers of signer type must sign sequentially in order.
Expand All @@ -23,7 +25,6 @@

signer = Ilovepdf::Signature::Receiver.new(:signer,'name','[email protected]')
signer.phone = "34677231431" #Phone number with the country prefix at the beginning => "+34677231431", make sure you have enough credits.
signer.phone = "34677231431" #Phone number with the country prefix at the beginning => "+34677231431", make sure you have enough credits.

signature_element = Ilovepdf::Signature::SignatureElement.new(file1)
signature_element.set_position(x: 20,y: -20)
Expand Down
68 changes: 68 additions & 0 deletions samples/signature_form_pdf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require "bundler/setup"
require 'ilovepdf'

# You can call task class directly
pub_key = "YOUR_PUBLIC_KEY"
priv_key = "YOUR_PRIVATE_KEY"
my_task = Ilovepdf::Tool::Signature.new(pub_key, priv_key)

# Send additional parameters to obtain the information about the PDF and the information about the form elements
extra_params = Ilovepdf::ExtraUploadParams::Signature.new
extra_params.set_pdf_forms(true).set_pdf_info(true)
file = my_task.add_file('/path/to/file/sample.pdf',extra_params)

# Define the signer
signer = Ilovepdf::Signature::Receiver.new(:signer,'name','[email protected]')

# Get number of pages
file.pdf_page_number
# get specific pdf page
pdf_page = file.pdf_page_info(1)
puts pdf_page.width
puts pdf_page.height

# Now we can loop over all of the form elements on the PDF
file.each_pdf_form_element do |form_element, pdf_page_info|
type_of_field = form_element["typeOfField"]
next unless ["textbox", "signature"].include?(type_of_field)

field_id = form_element["fieldId"]
widgets = form_element["widgetsInformation"]
position = widgets[0]
current_page = position["page"]

left_pos = position["left"]
top_position = position["top"] - pdf_page_info["height"]
size = (position["left"] - position["bottom"]).floor

if type_of_field == "textbox"
if form_element["multilineFlag"] || form_element["passwordFlag"]
next
end

text_value = form_element["textValue"]
# For instance, we want to create an input element if the label of the form contains the word "Input".
if field_id.include?('_input')
input_element = ElementInput.new
input_element.set_position(left_pos, top_position)
.set_size(size)
.set_label(text_value)
.set_pages(current_page.to_s)
elements << input_element
else
text_element = ElementText.new
text_element.set_position(left_pos, top_position)
.set_size(size)
.set_text(text_value)
.set_pages(current_page.to_s)
elements << text_element
end
elsif type_of_field == "signature"
signature_element = ElementSignature.new
signature_element.set_position(left_pos, top_position)
.set_size(size)
elements << signature_element
end
end


0 comments on commit 8c16c71

Please sign in to comment.