selectpdf 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/selectpdf.rb ADDED
@@ -0,0 +1,1528 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/https'
4
+ require 'json'
5
+ require 'fileutils'
6
+
7
+ #
8
+ # SelectPdf Online REST API Ruby client library. Contains a powerful HTML to PDF converter.
9
+ #
10
+ #
11
+ # Convert HTML to PDF
12
+ #
13
+ # {include:file:samples/simple_url_to_pdf.rb}
14
+ module SelectPdf
15
+ MULTIPART_FORM_DATA_BOUNDARY = '------------SelectPdf_Api_Boundry_$'
16
+ NEW_LINE = "\r\n"
17
+ CLIENT_VERSION = '1.3.0'
18
+
19
+ attr_reader :code, :message
20
+ #
21
+ # Exception thrown by SelectPdf API Client.
22
+ #
23
+ class ApiException < RuntimeError
24
+ # Class constructor
25
+ def initialize(message, code = nil)
26
+ super()
27
+ @message = message
28
+ @code = code
29
+ end
30
+
31
+ # Get complete error message
32
+ def to_s
33
+ @code ? "(#{@code}) #{@message}" : @message
34
+ end
35
+ end
36
+
37
+ # Base class for API clients. Do not use this directly.
38
+ class ApiClient
39
+ # API endpoint
40
+ attr_reader :api_endpoint
41
+
42
+ # API endpoint
43
+ attr_writer :api_endpoint
44
+
45
+ # API async jobs endpoint
46
+ attr_reader :api_async_endpoint
47
+
48
+ # API async jobs endpoint
49
+ attr_writer :api_async_endpoint
50
+
51
+ # API web elements endpoint
52
+ attr_reader :api_web_elements_endpoint
53
+
54
+ # API web elements endpoint
55
+ attr_writer :api_web_elements_endpoint
56
+
57
+ # Ping interval in seconds for asynchronous calls. Default value is 3 seconds.
58
+ attr_reader :async_calls_ping_interval
59
+
60
+ # Ping interval in seconds for asynchronous calls. Default value is 3 seconds.
61
+ attr_writer :async_calls_ping_interval
62
+
63
+ # Maximum number of pings for asynchronous calls. Default value is 1,000 pings.
64
+ attr_reader :async_calls_max_pings
65
+
66
+ # Maximum number of pings for asynchronous calls. Default value is 1,000 pings.
67
+ attr_writer :async_calls_max_pings
68
+
69
+ # Number of pages of the pdf document resulted from the conversion.
70
+ attr_reader :number_of_pages
71
+
72
+ # Class constructor
73
+ def initialize
74
+ # API endpoint
75
+ @api_endpoint = 'https://selectpdf.com/api2/convert/'
76
+
77
+ # API async jobs endpoint
78
+ @api_async_endpoint = 'https://selectpdf.com/api2/asyncjob/'
79
+
80
+ # API web elements endpoint
81
+ @api_web_elements_endpoint = 'https://selectpdf.com/api2/webelements/'
82
+
83
+ # Parameters that will be sent to the API.
84
+ @parameters = {}
85
+
86
+ # HTTP Headers that will be sent to the API.
87
+ @headers = {}
88
+
89
+ # Files that will be sent to the API.
90
+ @files = {}
91
+
92
+ # Binary data that will be sent to the API.
93
+ @binary_data = {}
94
+
95
+ # Number of pages of the pdf document resulted from the conversion.
96
+ @number_of_pages = 0
97
+
98
+ # Job ID for asynchronous calls or for calls that require a second request.
99
+ @job_id = ''
100
+
101
+ # Ping interval in seconds for asynchronous calls. Default value is 3 seconds.
102
+ @async_calls_ping_interval = 3
103
+
104
+ # Maximum number of pings for asynchronous calls. Default value is 1,000 pings.
105
+ @async_calls_max_pings = 1000
106
+ end
107
+
108
+ # Create a POST request.
109
+ #
110
+ # @param out_stream Output response to this stream, if specified.
111
+ # @return If output stream is not specified, return response.
112
+ def perform_post(out_stream = nil)
113
+ # reset results
114
+ @number_of_pages = 0
115
+ @job_id = ''
116
+
117
+ uri = URI(api_endpoint)
118
+ http = Net::HTTP.new(uri.host, uri.port)
119
+ http.use_ssl = @api_endpoint.downcase.start_with?('https')
120
+ http.read_timeout = 600 # timeout in seconds 600s=10minutes
121
+
122
+ http.start do |connection|
123
+ request = Net::HTTP::Post.new uri.request_uri
124
+ request.set_form_data(@parameters)
125
+
126
+ # add headers
127
+ request['selectpdf-api-client'] = "ruby-#{RUBY_VERSION}-#{CLIENT_VERSION}"
128
+ request['Content-Type'] = 'application/x-www-form-urlencoded'
129
+ @headers.each do |key, value|
130
+ request[key] = value
131
+ end
132
+
133
+ connection.request request do |response|
134
+ case response
135
+ when Net::HTTPSuccess
136
+ # all ok
137
+ @number_of_pages = (response['selectpdf-api-pages'] || 0).to_i
138
+ @job_id = response['selectpdf-api-jobid']
139
+
140
+ return response.body unless out_stream # return response if out_stream is not provided
141
+
142
+ # out_steam is provided - write to it
143
+ response.read_body do |chunk|
144
+ out_stream.write chunk
145
+ end
146
+ when Net::HTTPAccepted
147
+ # request accepted (for asynchronous jobs)
148
+ @job_id = response['selectpdf-api-jobid']
149
+
150
+ return nil
151
+ else
152
+ # error - get error message
153
+ raise ApiException.new(response.body, response.code), response.body
154
+ end
155
+ end
156
+ end
157
+ rescue ApiException
158
+ raise
159
+ rescue SocketError => e
160
+ raise ApiException.new("Socket Error: #{e}"), "Socket Error: #{e}"
161
+ rescue Timeout::Error
162
+ raise ApiException.new("Connection Timeout: #{http.read_timeout}s exceeded"), "Connection Timeout: #{http.read_timeout}s exceeded"
163
+ rescue OpenSSL::SSL::SSLError => e
164
+ raise ApiException.new("SSL Error: #{e}"), "SSL Error: #{e}"
165
+ rescue StandardError => e
166
+ raise ApiException.new("Connection refused: #{e}"), "Connection refused: #{e}"
167
+ end
168
+ protected :perform_post
169
+
170
+ # Create a multipart/form-data POST request (that can handle file uploads).
171
+ #
172
+ # @param out_stream Output response to this stream, if specified.
173
+ # @return If output stream is not specified, return response.
174
+ def perform_post_as_multipart_formdata(out_stream = nil)
175
+ # reset results
176
+ @number_of_pages = 0
177
+ @job_id = ''
178
+
179
+ uri = URI(api_endpoint)
180
+ http = Net::HTTP.new(uri.host, uri.port)
181
+ http.use_ssl = @api_endpoint.downcase.start_with?('https')
182
+ http.read_timeout = 600 # timeout in seconds 600s=10minutes
183
+
184
+ http.start do |connection|
185
+ request = Net::HTTP::Post.new uri.request_uri
186
+ request.body = encode_multipart_form_data
187
+
188
+ # add headers
189
+ request['selectpdf-api-client'] = "ruby-#{RUBY_VERSION}-#{CLIENT_VERSION}"
190
+ request['Content-Type'] = "multipart/form-data; boundary=#{MULTIPART_FORM_DATA_BOUNDARY}"
191
+ request['Content-Length'] = request.body.length
192
+
193
+ @headers.each do |key, value|
194
+ request[key] = value
195
+ end
196
+
197
+ connection.request request do |response|
198
+ case response
199
+ when Net::HTTPSuccess
200
+ # all ok
201
+ @number_of_pages = (response['selectpdf-api-pages'] || 0).to_i
202
+ @job_id = response['selectpdf-api-jobid']
203
+
204
+ return response.body unless out_stream # return response if out_stream is not provided
205
+
206
+ # out_steam is provided - write to it
207
+ response.read_body do |chunk|
208
+ out_stream.write chunk
209
+ end
210
+ when Net::HTTPAccepted
211
+ # request accepted (for asynchronous jobs)
212
+ @job_id = response['selectpdf-api-jobid']
213
+
214
+ return nil
215
+ else
216
+ # error - get error message
217
+ raise ApiException.new(response.body, response.code), response.body
218
+ end
219
+ end
220
+ end
221
+ rescue ApiException
222
+ raise
223
+ rescue SocketError => e
224
+ raise ApiException.new("Socket Error: #{e}"), "Socket Error: #{e}"
225
+ rescue Timeout::Error
226
+ raise ApiException.new("Connection Timeout: #{http.read_timeout}s exceeded"), "Connection Timeout: #{http.read_timeout}s exceeded"
227
+ rescue OpenSSL::SSL::SSLError => e
228
+ raise ApiException.new("SSL Error: #{e}"), "SSL Error: #{e}"
229
+ rescue StandardError => e
230
+ raise ApiException.new("Connection refused: #{e}"), "Connection refused: #{e}"
231
+ end
232
+ protected :perform_post_as_multipart_formdata
233
+
234
+ # Encode data for multipart POST
235
+ def encode_multipart_form_data
236
+ data = []
237
+
238
+ # encode regular parameters
239
+ @parameters.each do |key, value|
240
+ data << '--' + MULTIPART_FORM_DATA_BOUNDARY << 'Content-Disposition: form-data; name="%s"' % key << '' << value.to_s if value
241
+ end
242
+
243
+ # encode files
244
+ @files.each do |key, value|
245
+ File.open(value, 'rb') do |f|
246
+ data << '--' + MULTIPART_FORM_DATA_BOUNDARY
247
+ data << 'Content-Disposition: form-data; name="%s"; filename="%s"' % [key, value]
248
+ data << 'Content-Type: application/octet-stream'
249
+ data << ''
250
+ data << f.read.force_encoding('UTF-8')
251
+ end
252
+ end
253
+
254
+ # encode additional binary data
255
+ @binary_data.each do |key, value|
256
+ data << '--' + MULTIPART_FORM_DATA_BOUNDARY
257
+ data << 'Content-Disposition: form-data; name="%s"; filename="%s"' % [key, key]
258
+ data << 'Content-Type: application/octet-stream'
259
+ data << ''
260
+ data << value.force_encoding('UTF-8')
261
+ end
262
+
263
+ # final boundary
264
+ data << '--' + MULTIPART_FORM_DATA_BOUNDARY + '--'
265
+ data << ''
266
+
267
+ data.join(NEW_LINE)
268
+ end
269
+ private :encode_multipart_form_data
270
+
271
+ # Start an asynchronous job.
272
+ #
273
+ # @return Asynchronous job ID.
274
+ def start_async_job
275
+ @parameters['async'] = 'True'
276
+ perform_post
277
+ @job_id
278
+ end
279
+ protected :start_async_job
280
+
281
+ # Start an asynchronous job that requires multipart forma data.
282
+ #
283
+ # @return Asynchronous job ID.
284
+ def start_async_job_multipart_form_data
285
+ @parameters['async'] = 'True'
286
+ perform_post_as_multipart_formdata
287
+ @job_id
288
+ end
289
+ protected :start_async_job_multipart_form_data
290
+ end
291
+
292
+ # Get usage details for SelectPdf Online API.
293
+ class UsageClient < ApiClient
294
+ # Construct the Usage client.
295
+ #
296
+ # @param api_key API Key.
297
+ def initialize(api_key)
298
+ super()
299
+ @api_endpoint = 'https://selectpdf.com/api2/usage/'
300
+ @parameters['key'] = api_key
301
+ end
302
+
303
+ # Get API usage information with history if specified.
304
+ #
305
+ # @param get_history Get history or not.
306
+ # @return Usage information.
307
+ def get_usage(get_history = false)
308
+ @headers['Accept'] = 'text/json'
309
+ @parameters['get_history'] = 'True' if get_history
310
+
311
+ result = perform_post
312
+ JSON.parse(result)
313
+ end
314
+ end
315
+
316
+ # PDF page size.
317
+ class PageSize
318
+ # Custom page size.
319
+ CUSTOM = 'Custom'
320
+
321
+ # A0 page size.
322
+ A0 = 'A0'
323
+
324
+ # A1 page size.
325
+ A1 = 'A1'
326
+
327
+ # A2 page size.
328
+ A2 = 'A2'
329
+
330
+ # A3 page size.
331
+ A3 = 'A3'
332
+
333
+ # A4 page size.
334
+ A4 = 'A4'
335
+
336
+ # A5 page size.
337
+ A5 = 'A5'
338
+
339
+ # A6 page size.
340
+ A6 = 'A6'
341
+
342
+ # A7 page size.
343
+ A7 = 'A7'
344
+
345
+ # A8 page size.
346
+ A8 = 'A8'
347
+
348
+ # Letter page size.
349
+ LETTER = 'Letter'
350
+
351
+ # Half Letter page size.
352
+ HALF_LETTER = 'HalfLetter'
353
+
354
+ # Ledger page size.
355
+ LEDGER = 'Ledger'
356
+
357
+ # A5 page size.
358
+ LEGAL = 'Legal'
359
+ end
360
+
361
+ # PDF page orientation.
362
+ class PageOrientation
363
+ # Portrait page orientation.
364
+ PORTRAIT = 'Portrait'
365
+
366
+ # Landscape page orientation.
367
+ LANDSCAPE = 'Landscape'
368
+ end
369
+
370
+ # Rendering engine used for HTML to PDF conversion.
371
+ class RenderingEngine
372
+ # WebKit rendering engine.
373
+ WEBKIT = 'WebKit'
374
+
375
+ # WebKit Restricted rendering engine.
376
+ RESTRICTED = 'Restricted'
377
+
378
+ # Blink rendering engine.
379
+ BLINK = 'Blink'
380
+ end
381
+
382
+ # Protocol used for secure (HTTPS) connections.
383
+ class SecureProtocol
384
+ # TLS 1.1 or newer. Recommended value.
385
+ TLS_11_OR_NEWER = 0
386
+
387
+ # TLS 1.0 only.
388
+ TLS10 = 1
389
+
390
+ # SSL v3 only.
391
+ SSL3 = 2
392
+ end
393
+
394
+ # The page layout to be used when the pdf document is opened in a viewer.
395
+ class PageLayout
396
+ # Displays one page at a time.
397
+ SINGLE_PAGE = 0
398
+
399
+ # Displays the pages in one column.
400
+ ONE_COLUMN = 1
401
+
402
+ # Displays the pages in two columns, with odd-numbered pages on the left.
403
+ TWO_COLUMN_LEFT = 2
404
+
405
+ # Displays the pages in two columns, with odd-numbered pages on the right.
406
+ TWO_COLUMN_RIGHT = 3
407
+ end
408
+
409
+ # The PDF document's page mode.
410
+ class PageMode
411
+ # Neither document outline (bookmarks) nor thumbnail images are visible.
412
+ USE_NONE = 0
413
+
414
+ # Document outline (bookmarks) are visible.
415
+ USE_OUTLINES = 1
416
+
417
+ # Thumbnail images are visible.
418
+ USE_THUMBS = 2
419
+
420
+ # Full-screen mode, with no menu bar, window controls or any other window visible.
421
+ FULL_SCREEN = 3
422
+
423
+ # Optional content group panel is visible.
424
+ USE_OC = 4
425
+
426
+ # Document attachments are visible.
427
+ USE_ATTACHMENTS = 5
428
+ end
429
+
430
+ # Alignment for page numbers.
431
+ class PageNumbersAlignment
432
+ # Align left.
433
+ LEFT = 1
434
+
435
+ # Align center.
436
+ CENTER = 2
437
+
438
+ # Align right.
439
+ RIGHT = 3
440
+ end
441
+
442
+ # Specifies the converter startup mode.
443
+ class StartupMode
444
+ # The conversion starts right after the page loads.
445
+ AUTOMATIC = 'Automatic'
446
+
447
+ # The conversion starts only when called from JavaScript.
448
+ MANUAL = 'Manual'
449
+ end
450
+
451
+ # The output text layout (for pdf to text calls).
452
+ class TextLayout
453
+ # The original layout of the text from the PDF document is preserved.
454
+ ORIGINAL = 0
455
+
456
+ # The text is produced in reading order.
457
+ READING = 1
458
+ end
459
+
460
+ # The output format (for pdf to text calls).
461
+ class OutputFormat
462
+ # Text
463
+ TEXT = 0
464
+
465
+ # Html
466
+ HTML = 1
467
+ end
468
+
469
+ # Html To Pdf Conversion with SelectPdf Online API.
470
+ #
471
+ # Code sample:
472
+ #
473
+ # {include:file:samples/html_to_pdf_main.rb}
474
+ class HtmlToPdfClient < ApiClient
475
+ # Construct the Html To Pdf Client.
476
+ #
477
+ # @param api_key API Key.
478
+ def initialize(api_key)
479
+ super()
480
+ @api_endpoint = 'https://selectpdf.com/api2/convert/'
481
+ @parameters['key'] = api_key
482
+ end
483
+
484
+ # Convert the specified url to PDF.
485
+ # SelectPdf online API can convert http:// and https:// publicly available urls.
486
+ #
487
+ # @param url Address of the web page being converted.
488
+ # @return The resulted pdf.
489
+ def convert_url(url)
490
+ if !url.downcase.start_with?('http://') && !url.downcase.start_with?('https://')
491
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
492
+ end
493
+
494
+ if url.downcase.start_with?('http://localhost')
495
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
496
+ end
497
+
498
+ @parameters['url'] = url
499
+ @parameters.delete('html')
500
+ @parameters.delete('base_url')
501
+ @parameters['async'] = 'False'
502
+
503
+ perform_post
504
+ end
505
+
506
+ # Convert the specified url to PDF and writes the resulted PDF to an output stream.
507
+ # SelectPdf online API can convert http:// and https:// publicly available urls.
508
+ #
509
+ # @param url Address of the web page being converted.
510
+ # @param stream The output stream where the resulted PDF will be written.
511
+ def convert_url_to_stream(url, stream)
512
+ if !url.downcase.start_with?('http://') && !url.downcase.start_with?('https://')
513
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
514
+ end
515
+
516
+ if url.downcase.start_with?('http://localhost')
517
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
518
+ end
519
+
520
+ @parameters['url'] = url
521
+ @parameters.delete('html')
522
+ @parameters.delete('base_url')
523
+ @parameters['async'] = 'False'
524
+
525
+ perform_post(stream)
526
+ end
527
+
528
+ # Convert the specified url to PDF and writes the resulted PDF to a local file.
529
+ # SelectPdf online API can convert http:// and https:// publicly available urls.
530
+ #
531
+ # @param url Address of the web page being converted.
532
+ # @param file_path Local file including path if necessary.
533
+ def convert_url_to_file(url, file_path)
534
+ if !url.downcase.start_with?('http://') && !url.downcase.start_with?('https://')
535
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
536
+ end
537
+
538
+ if url.downcase.start_with?('http://localhost')
539
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
540
+ end
541
+
542
+ @parameters['url'] = url
543
+ @parameters.delete('html')
544
+ @parameters.delete('base_url')
545
+ @parameters['async'] = 'False'
546
+
547
+ begin
548
+ File.open(file_path, 'wb') do |file|
549
+ perform_post(file)
550
+ end
551
+ rescue ApiException
552
+ FileUtils.rm(file_path) if File.exist?(file_path)
553
+ raise
554
+ end
555
+ end
556
+
557
+ # Convert the specified url to PDF using an asynchronous call.
558
+ # SelectPdf online API can convert http:// and https:// publicly available urls.
559
+ #
560
+ # @param url Address of the web page being converted.
561
+ # @return The resulted pdf.
562
+ def convert_url_async(url)
563
+ if !url.downcase.start_with?('http://') && !url.downcase.start_with?('https://')
564
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
565
+ end
566
+
567
+ if url.downcase.start_with?('http://localhost')
568
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
569
+ end
570
+
571
+ @parameters['url'] = url
572
+ @parameters.delete('html')
573
+ @parameters.delete('base_url')
574
+
575
+ job_id = start_async_job
576
+
577
+ if job_id.nil? || job_id.empty?
578
+ raise ApiException.new('An error occurred launching the asynchronous call.'), 'An error occurred launching the asynchronous call.'
579
+ end
580
+
581
+ no_pings = 0
582
+
583
+ while no_pings < @async_calls_max_pings
584
+ no_pings += 1
585
+
586
+ # sleep for a few seconds before next ping
587
+ sleep(@async_calls_ping_interval)
588
+
589
+ async_job_client = AsyncJobClient.new(@parameters['key'], @job_id)
590
+ async_job_client.api_endpoint = @api_async_endpoint
591
+
592
+ result = async_job_client.result
593
+
594
+ next if result.nil?
595
+
596
+ @number_of_pages = async_job_client.number_of_pages
597
+ return result
598
+ end
599
+
600
+ raise ApiException.new('Asynchronous call did not finish in expected timeframe.'), 'Asynchronous call did not finish in expected timeframe.'
601
+ end
602
+
603
+ # Convert the specified url to PDF using an asynchronous call and writes the resulted PDF to an output stream.
604
+ # SelectPdf online API can convert http:// and https:// publicly available urls.
605
+ #
606
+ # @param url Address of the web page being converted.
607
+ # @param stream The output stream where the resulted PDF will be written.
608
+ def convert_url_to_stream_async(url, stream)
609
+ result = convert_url_async(url)
610
+ stream.write(result)
611
+ end
612
+
613
+ # Convert the specified url to PDF using an asynchronous call and writes the resulted PDF to a local file.
614
+ # SelectPdf online API can convert http:// and https:// publicly available urls.
615
+ #
616
+ # @param url Address of the web page being converted.
617
+ # @param file_path Local file including path if necessary.
618
+ def convert_url_to_file_async(url, file_path)
619
+ result = convert_url_async(url)
620
+ File.open(file_path, 'wb') do |file|
621
+ file.write(result)
622
+ end
623
+ rescue ApiException
624
+ FileUtils.rm(file_path) if File.exist?(file_path)
625
+ raise
626
+ end
627
+
628
+ # Convert the specified HTML string to PDF. Use a base url to resolve relative paths to resources.
629
+ #
630
+ # @param html_string HTML string with the content being converted.
631
+ # @param base_url Base url used to resolve relative paths to resources (css, images, javascript, etc). Must be a http:// or https:// publicly available url.
632
+ def convert_html_string_with_base_url(html_string, base_url)
633
+ @parameters.delete('url')
634
+ @parameters['async'] = 'False'
635
+ @parameters['html'] = html_string
636
+ @parameters['base_url'] = base_url unless base_url.nil? || base_url.empty?
637
+
638
+ perform_post
639
+ end
640
+
641
+ # Convert the specified HTML string to PDF and writes the resulted PDF to an output stream. Use a base url to resolve relative paths to resources.
642
+ #
643
+ # @param html_string HTML string with the content being converted.
644
+ # @param base_url Base url used to resolve relative paths to resources (css, images, javascript, etc). Must be a http:// or https:// publicly available url.
645
+ # @param stream The output stream where the resulted PDF will be written.
646
+ def convert_html_string_to_stream_with_base_url(html_string, base_url, stream)
647
+ @parameters.delete('url')
648
+ @parameters['async'] = 'False'
649
+ @parameters['html'] = html_string
650
+ @parameters['base_url'] = base_url unless base_url.nil? || base_url.empty?
651
+
652
+ perform_post(stream)
653
+ end
654
+
655
+ # Convert the specified HTML string to PDF and writes the resulted PDF to a local file. Use a base url to resolve relative paths to resources.
656
+ #
657
+ # @param html_string HTML string with the content being converted.
658
+ # @param base_url Base url used to resolve relative paths to resources (css, images, javascript, etc). Must be a http:// or https:// publicly available url.
659
+ # @param file_path Local file including path if necessary.
660
+ def convert_html_string_with_base_url_to_file(html_string, base_url, file_path)
661
+ @parameters.delete('url')
662
+ @parameters['async'] = 'False'
663
+ @parameters['html'] = html_string
664
+ @parameters['base_url'] = base_url unless base_url.nil? || base_url.empty?
665
+
666
+ begin
667
+ File.open(file_path, 'wb') do |file|
668
+ perform_post(file)
669
+ end
670
+ rescue ApiException
671
+ FileUtils.rm(file_path) if File.exist?(file_path)
672
+ raise
673
+ end
674
+ end
675
+
676
+ # Convert the specified HTML string to PDF with an asynchronous call. Use a base url to resolve relative paths to resources.
677
+ #
678
+ # @param html_string HTML string with the content being converted.
679
+ # @param base_url Base url used to resolve relative paths to resources (css, images, javascript, etc). Must be a http:// or https:// publicly available url.
680
+ def convert_html_string_with_base_url_async(html_string, base_url)
681
+ @parameters.delete('url')
682
+ @parameters['html'] = html_string
683
+ @parameters['base_url'] = base_url unless base_url.nil? || base_url.empty?
684
+
685
+ job_id = start_async_job
686
+
687
+ if job_id.nil? || job_id.empty?
688
+ raise ApiException.new('An error occurred launching the asynchronous call.'), 'An error occurred launching the asynchronous call.'
689
+ end
690
+
691
+ no_pings = 0
692
+
693
+ while no_pings < @async_calls_max_pings
694
+ no_pings += 1
695
+
696
+ # sleep for a few seconds before next ping
697
+ sleep(@async_calls_ping_interval)
698
+
699
+ async_job_client = AsyncJobClient.new(@parameters['key'], @job_id)
700
+ async_job_client.api_endpoint = @api_async_endpoint
701
+
702
+ result = async_job_client.result
703
+
704
+ next if result.nil?
705
+
706
+ @number_of_pages = async_job_client.number_of_pages
707
+ return result
708
+ end
709
+
710
+ raise ApiException.new('Asynchronous call did not finish in expected timeframe.'), 'Asynchronous call did not finish in expected timeframe.'
711
+ end
712
+
713
+ # Convert the specified HTML string to PDF with an asynchronous call and writes the resulted PDF to an output stream. Use a base url to resolve relative paths to resources.
714
+ #
715
+ # @param html_string HTML string with the content being converted.
716
+ # @param base_url Base url used to resolve relative paths to resources (css, images, javascript, etc). Must be a http:// or https:// publicly available url.
717
+ # @param stream The output stream where the resulted PDF will be written.
718
+ def convert_html_string_to_stream_with_base_url_async(html_string, base_url, stream)
719
+ result = convert_html_string_with_base_url_async(html_string, base_url)
720
+ stream.write(result)
721
+ end
722
+
723
+ # Convert the specified HTML string to PDF with an asynchronous call and writes the resulted PDF to a local file. Use a base url to resolve relative paths to resources.
724
+ #
725
+ # @param html_string HTML string with the content being converted.
726
+ # @param base_url Base url used to resolve relative paths to resources (css, images, javascript, etc). Must be a http:// or https:// publicly available url.
727
+ # @param file_path Local file including path if necessary.
728
+ def convert_html_string_with_base_url_to_file_async(html_string, base_url, file_path)
729
+ result = convert_html_string_with_base_url_async(html_string, base_url)
730
+ File.open(file_path, 'wb') do |file|
731
+ file.write(result)
732
+ end
733
+ rescue ApiException
734
+ FileUtils.rm(file_path) if File.exist?(file_path)
735
+ raise
736
+ end
737
+
738
+ # Convert the specified HTML string to PDF.
739
+ #
740
+ # @param html_string HTML string with the content being converted.
741
+ def convert_html_string(html_string)
742
+ convert_html_string_with_base_url(html_string, nil)
743
+ end
744
+
745
+ # Convert the specified HTML string to PDF and writes the resulted PDF to an output stream.
746
+ #
747
+ # @param html_string HTML string with the content being converted.
748
+ # @param stream The output stream where the resulted PDF will be written.
749
+ def convert_html_string_to_stream(html_string, stream)
750
+ convert_html_string_to_stream_with_base_url(html_string, nil, stream)
751
+ end
752
+
753
+ # Convert the specified HTML string to PDF and writes the resulted PDF to a local file.
754
+ #
755
+ # @param html_string HTML string with the content being converted.
756
+ # @param file_path Local file including path if necessary.
757
+ def convert_html_string_to_file(html_string, file_path)
758
+ convert_html_string_with_base_url_to_file(html_string, nil, file_path)
759
+ end
760
+
761
+ # Convert the specified HTML string to PDF with an asynchronous call.
762
+ #
763
+ # @param html_string HTML string with the content being converted.
764
+ def convert_html_string_async(html_string)
765
+ convert_html_string_with_base_url_async(html_string, nil)
766
+ end
767
+
768
+ # Convert the specified HTML string to PDF with an asynchronous call and writes the resulted PDF to an output stream.
769
+ #
770
+ # @param html_string HTML string with the content being converted.
771
+ # @param stream The output stream where the resulted PDF will be written.
772
+ def convert_html_string_to_stream_async(html_string, stream)
773
+ convert_html_string_to_stream_with_base_url_async(html_string, nil, stream)
774
+ end
775
+
776
+ # Convert the specified HTML string to PDF with an asynchronous call and writes the resulted PDF to a local file.
777
+ #
778
+ # @param html_string HTML string with the content being converted.
779
+ # @param file_path Local file including path if necessary.
780
+ def convert_html_string_to_file_async(html_string, file_path)
781
+ convert_html_string_with_base_url_to_file_async(html_string, nil, file_path)
782
+ end
783
+
784
+ # Set PDF page size. Default value is A4.
785
+ # If page size is set to Custom, use setPageWidth and setPageHeight methods to set the custom width/height of the PDF pages.
786
+ #
787
+ # @param page_size PDF page size. Possible values: Custom, A0, A1, A2, A3, A4, A5, A6, A7, A8, Letter, HalfLetter, Ledger, Legal. Use constants from SelectPdf::PageSize class.
788
+ def page_size=(page_size)
789
+ unless /(?i)^(Custom|A0|A1|A2|A3|A4|A5|A6|A7|A8|Letter|HalfLetter|Ledger|Legal)$/.match(page_size)
790
+ raise ApiException.new('Allowed values for Page Size: Custom, A0, A1, A2, A3, A4, A5, A6, A7, A8, Letter, HalfLetter, Ledger, Legal.'), 'Allowed values for Page Size: Custom, A0, A1, A2, A3, A4, A5, A6, A7, A8, Letter, HalfLetter, Ledger, Legal.'
791
+ end
792
+
793
+ @parameters['page_size'] = page_size
794
+ end
795
+
796
+ # Set PDF page width in points. Default value is 595pt (A4 page width in points). 1pt = 1/72 inch.
797
+ # This is taken into account only if page size is set to SelectPdf::PageSize::CUSTOM using page_size property.
798
+ #
799
+ # @param page_width Page width in points.
800
+ def page_width=(page_width)
801
+ @parameters['page_width'] = page_width
802
+ end
803
+
804
+ # Set PDF page height in points. Default value is 842pt (A4 page height in points). 1pt = 1/72 inch.
805
+ # This is taken into account only if page size is set to SelectPdf::PageSize::CUSTOM using page_size property.
806
+ #
807
+ # @param page_height Page height in points.
808
+ def page_height=(page_height)
809
+ @parameters['page_height'] = page_height
810
+ end
811
+
812
+ # Set PDF page orientation. Default value is Portrait.
813
+ #
814
+ # @param page_orientation PDF page orientation. Possible values: Portrait, Landscape. Use constants from SelectPdf::PageOrientation class.
815
+ def page_orientation=(page_orientation)
816
+ unless /(?i)^(Portrait|Landscape)$/.match(page_orientation)
817
+ raise ApiException.new('Allowed values for Page Orientation: Portrait, Landscape.'), 'Allowed values for Page Orientation: Portrait, Landscape.'
818
+ end
819
+
820
+ @parameters['page_orientation'] = page_orientation
821
+ end
822
+
823
+ # Set top margin of the PDF pages. Default value is 5pt.
824
+ #
825
+ # @param margin_top Margin value in points. 1pt = 1/72 inch.
826
+ def margin_top=(margin_top)
827
+ @parameters['margin_top'] = margin_top
828
+ end
829
+
830
+ # Set right margin of the PDF pages. Default value is 5pt.
831
+ #
832
+ # @param margin_right Margin value in points. 1pt = 1/72 inch.
833
+ def margin_right=(margin_right)
834
+ @parameters['margin_right'] = margin_right
835
+ end
836
+
837
+ # Set bottom margin of the PDF pages. Default value is 5pt.
838
+ #
839
+ # @param margin_bottom Margin value in points. 1pt = 1/72 inch.
840
+ def margin_bottom=(margin_bottom)
841
+ @parameters['margin_bottom'] = margin_bottom
842
+ end
843
+
844
+ # Set left margin of the PDF pages. Default value is 5pt.
845
+ #
846
+ # @param margin_left Margin value in points. 1pt = 1/72 inch.
847
+ def margin_left=(margin_left)
848
+ @parameters['margin_left'] = margin_left
849
+ end
850
+
851
+ # Set all margins of the PDF pages to the same value. Default value is 5pt.
852
+ #
853
+ # @param margin Margin value in points. 1pt = 1/72 inch.
854
+ def margins=(margin)
855
+ @parameters['margin_top'] = margin
856
+ @parameters['margin_right'] = margin
857
+ @parameters['margin_bottom'] = margin
858
+ @parameters['margin_left'] = margin
859
+ end
860
+
861
+ # Specify the name of the pdf document that will be created. The default value is Document.pdf.
862
+ #
863
+ # @param pdf_name Name of the generated PDF document.
864
+ def pdf_name=(pdf_name)
865
+ @parameters['pdf_name'] = pdf_name
866
+ end
867
+
868
+ # Set the rendering engine used for the HTML to PDF conversion. Default value is WebKit.
869
+ #
870
+ # @param rendering_engine HTML rendering engine. Use constants from SelectPdf::RenderingEngine class.
871
+ def rendering_engine=(rendering_engine)
872
+ unless /(?i)^(WebKit|Restricted|Blink)$/.match(rendering_engine)
873
+ raise ApiException.new('Allowed values for Rendering Engine: WebKit, Restricted, Blink.'), 'Allowed values for Rendering Engine: WebKit, Restricted, Blink.'
874
+ end
875
+
876
+ @parameters['engine'] = rendering_engine
877
+ end
878
+
879
+ # Set PDF user password.
880
+ #
881
+ # @param user_password PDF user password.
882
+ def user_password=(user_password)
883
+ @parameters['user_password'] = user_password
884
+ end
885
+
886
+ # Set PDF owner password.
887
+ #
888
+ # @param owner_password PDF owner password.
889
+ def owner_password=(owner_password)
890
+ @parameters['owner_password'] = owner_password
891
+ end
892
+
893
+ # Set the width used by the converter's internal browser window in pixels. The default value is 1024px.
894
+ #
895
+ # @param web_page_width Browser window width in pixels.
896
+ def web_page_width=(web_page_width)
897
+ @parameters['web_page_width'] = web_page_width
898
+ end
899
+
900
+ # Set the height used by the converter's internal browser window in pixels.
901
+ # The default value is 0px and it means that the page height is automatically calculated by the converter.
902
+ #
903
+ # @param web_page_height Browser window height in pixels. Set it to 0px to automatically calculate page height.
904
+ def web_page_height=(web_page_height)
905
+ @parameters['web_page_height'] = web_page_height
906
+ end
907
+
908
+ # Introduce a delay (in seconds) before the actual conversion to allow the web page to fully load. This property is an alias for conversion_delay.
909
+ # The default value is 1 second. Use a larger value if the web page has content that takes time to render when it is displayed in the browser.
910
+ #
911
+ # @param min_load_time Delay in seconds.
912
+ def min_load_time=(min_load_time)
913
+ @parameters['min_load_time'] = min_load_time
914
+ end
915
+
916
+ # Introduce a delay (in seconds) before the actual conversion to allow the web page to fully load. This method is an alias for min_load_time.
917
+ # The default value is 1 second. Use a larger value if the web page has content that takes time to render when it is displayed in the browser.
918
+ #
919
+ # @param conversion_delay Delay in seconds.
920
+ def conversion_delay=(conversion_delay)
921
+ self.min_load_time = conversion_delay
922
+ end
923
+
924
+ # Set the maximum amount of time (in seconds) that the convert will wait for the page to load. This method is an alias for navigation_timeout.
925
+ # A timeout error is displayed when this time elapses. The default value is 30 seconds. Use a larger value (up to 120 seconds allowed) for pages that take a long time to load.
926
+ #
927
+ # @param max_load_time Timeout in seconds.
928
+ def max_load_time=(max_load_time)
929
+ @parameters['max_load_time'] = max_load_time
930
+ end
931
+
932
+ # Set the maximum amount of time (in seconds) that the convert will wait for the page to load. This method is an alias for max_load_time.
933
+ # A timeout error is displayed when this time elapses. The default value is 30 seconds. Use a larger value (up to 120 seconds allowed) for pages that take a long time to load.
934
+ #
935
+ # @param navigation_timeout Timeout in seconds.
936
+ def navigation_timeout=(navigation_timeout)
937
+ self.max_load_time = navigation_timeout
938
+ end
939
+
940
+ # Set the protocol used for secure (HTTPS) connections. Set this only if you have an older server that only works with older SSL connections.
941
+ #
942
+ # @param secure_protocol Secure protocol. Possible values: 0 (TLS 1.1 or newer), 1 (TLS 1.0), 2 (SSL v3 only). Use constants from SelectPdf::SecureProtocol class.
943
+ def secure_protocol=(secure_protocol)
944
+ unless [0, 1, 2].include?(secure_protocol)
945
+ raise ApiException.new('Allowed values for Secure Protocol: 0 (TLS 1.1 or newer), 1 (TLS 1.0), 2 (SSL v3 only).'), 'Allowed values for Secure Protocol: 0 (TLS 1.1 or newer), 1 (TLS 1.0), 2 (SSL v3 only).'
946
+ end
947
+
948
+ @parameters['protocol'] = secure_protocol
949
+ end
950
+
951
+ # Specify if the CSS Print media type is used instead of the Screen media type. The default value is FALSE.
952
+ #
953
+ # @param use_css_print Use CSS Print media or not.
954
+ def use_css_print=(use_css_print)
955
+ @parameters['use_css_print'] = use_css_print
956
+ end
957
+
958
+ # Specify the background color of the PDF page in RGB html format. The default is #FFFFFF.
959
+ #
960
+ # @param background_color Background color in #RRGGBB format.
961
+ def background_color=(background_color)
962
+ unless /^#?[0-9a-fA-F]{6}$/.match(background_color)
963
+ raise ApiException.new('Color value must be in #RRGGBB format.'), 'Color value must be in #RRGGBB format.'
964
+ end
965
+
966
+ @parameters['background_color'] = background_color
967
+ end
968
+
969
+ # Set a flag indicating if the web page background is rendered in PDF. The default value is TRUE.
970
+ #
971
+ # @param draw_html_background Draw the HTML background or not.
972
+ def draw_html_background=(draw_html_background)
973
+ @parameters['draw_html_background'] = draw_html_background
974
+ end
975
+
976
+ # Do not run JavaScript in web pages. The default value is False and javascript is executed.
977
+ #
978
+ # @param disable_javascript Disable javascript or not.
979
+ def disable_javascript=(disable_javascript)
980
+ @parameters['disable_javascript'] = disable_javascript
981
+ end
982
+
983
+ # Do not create internal links in the PDF. The default value is False and internal links are created.
984
+ #
985
+ # @param disable_internal_links Disable internal links or not.
986
+ def disable_internal_links=(disable_internal_links)
987
+ @parameters['disable_internal_links'] = disable_internal_links
988
+ end
989
+
990
+ # Do not create external links in the PDF. The default value is False and external links are created.
991
+ #
992
+ # @param disable_external_links Disable external links or not.
993
+ def disable_external_links=(disable_external_links)
994
+ @parameters['disable_external_links'] = disable_external_links
995
+ end
996
+
997
+ # Try to render the PDF even in case of the web page loading timeout. The default value is False and an exception is raised in case of web page navigation timeout.
998
+ #
999
+ # @param render_on_timeout Render in case of timeout or not.
1000
+ def render_on_timeout=(render_on_timeout)
1001
+ @parameters['render_on_timeout'] = render_on_timeout
1002
+ end
1003
+
1004
+ # Avoid breaking images between PDF pages. The default value is False and images are split between pages if larger.
1005
+ #
1006
+ # @param keep_images_together Try to keep images on same page or not.
1007
+ def keep_images_together=(keep_images_together)
1008
+ @parameters['keep_images_together'] = keep_images_together
1009
+ end
1010
+
1011
+ # Set the PDF document title.
1012
+ #
1013
+ # @param doc_title Document title.
1014
+ def doc_title=(doc_title)
1015
+ @parameters['doc_title'] = doc_title
1016
+ end
1017
+
1018
+ # Set the subject of the PDF document.
1019
+ #
1020
+ # @param doc_subject Document subject.
1021
+ def doc_subject=(doc_subject)
1022
+ @parameters['doc_subject'] = doc_subject
1023
+ end
1024
+
1025
+ # Set the PDF document keywords.
1026
+ #
1027
+ # @param doc_keywords Document keywords.
1028
+ def doc_keywords=(doc_keywords)
1029
+ @parameters['doc_keywords'] = doc_keywords
1030
+ end
1031
+
1032
+ # Set the name of the PDF document author.
1033
+ #
1034
+ # @param doc_author Document author.
1035
+ def doc_author=(doc_author)
1036
+ @parameters['doc_author'] = doc_author
1037
+ end
1038
+
1039
+ # Add the date and time when the PDF document was created to the PDF document information. The default value is False.
1040
+ #
1041
+ # @param doc_add_creation_date Add creation date to the document metadata or not.
1042
+ def doc_add_creation_date=(doc_add_creation_date)
1043
+ @parameters['doc_add_creation_date'] = doc_add_creation_date
1044
+ end
1045
+
1046
+ # Set the page layout to be used when the document is opened in a PDF viewer. The default value is SelectPdf::PageLayout::ONE_COLUMN.
1047
+ #
1048
+ # @param viewer_page_layout Page layout. Possible values: 0 (Single Page), 1 (One Column), 2 (Two Column Left), 3 (Two Column Right).
1049
+ # Use constants from SelectPdf::PageLayout class.
1050
+ def viewer_page_layout=(viewer_page_layout)
1051
+ unless [0, 1, 2, 3].include?(viewer_page_layout)
1052
+ raise ApiException.new('Allowed values for Page Layout: 0 (Single Page), 1 (One Column), 2 (Two Column Left), 3 (Two Column Right).'), 'Allowed values for Page Layout: 0 (Single Page), 1 (One Column), 2 (Two Column Left), 3 (Two Column Right).'
1053
+ end
1054
+
1055
+ @parameters['viewer_page_layout'] = viewer_page_layout
1056
+ end
1057
+
1058
+ # Set the document page mode when the pdf document is opened in a PDF viewer. The default value is SelectPdf::PageMode::USE_NONE.
1059
+ #
1060
+ # @param viewer_page_mode Page mode. Possible values: 0 (Use None), 1 (Use Outlines), 2 (Use Thumbs), 3 (Full Screen), 4 (Use OC), 5 (Use Attachments).
1061
+ # Use constants from SelectPdf::PageMode class.
1062
+ def viewer_page_mode=(viewer_page_mode)
1063
+ unless [0, 1, 2, 3, 4, 5].include?(viewer_page_mode)
1064
+ raise ApiException.new('Allowed values for Page Mode: 0 (Use None), 1 (Use Outlines), 2 (Use Thumbs), 3 (Full Screen), 4 (Use OC), 5 (Use Attachments).'),
1065
+ 'Allowed values for Page Mode: 0 (Use None), 1 (Use Outlines), 2 (Use Thumbs), 3 (Full Screen), 4 (Use OC), 5 (Use Attachments).'
1066
+ end
1067
+
1068
+ @parameters['viewer_page_mode'] = viewer_page_mode
1069
+ end
1070
+
1071
+ # Set a flag specifying whether to position the document's window in the center of the screen. The default value is False.
1072
+ #
1073
+ # @param viewer_center_window Center window or not.
1074
+ def viewer_center_window=(viewer_center_window)
1075
+ @parameters['viewer_center_window'] = viewer_center_window
1076
+ end
1077
+
1078
+ # Set a flag specifying whether the window's title bar should display the document title taken from document information. The default value is False.
1079
+ #
1080
+ # @param viewer_display_doc_title Display title or not.
1081
+ def viewer_display_doc_title=(viewer_display_doc_title)
1082
+ @parameters['viewer_display_doc_title'] = viewer_display_doc_title
1083
+ end
1084
+
1085
+ # Set a flag specifying whether to resize the document's window to fit the size of the first displayed page. The default value is False.
1086
+ #
1087
+ # @param viewer_fit_window Fit window or not.
1088
+ def viewer_fit_window=(viewer_fit_window)
1089
+ @parameters['viewer_fit_window'] = viewer_fit_window
1090
+ end
1091
+
1092
+ # Set a flag specifying whether to hide the pdf viewer application's menu bar when the document is active. The default value is False.
1093
+ #
1094
+ # @param viewer_hide_menu_bar Hide menu bar or not.
1095
+ def viewer_hide_menu_bar=(viewer_hide_menu_bar)
1096
+ @parameters['viewer_hide_menu_bar'] = viewer_hide_menu_bar
1097
+ end
1098
+
1099
+ # Set a flag specifying whether to hide the pdf viewer application's tool bars when the document is active. The default value is False.
1100
+ #
1101
+ # @param viewer_hide_toolbar Hide tool bars or not.
1102
+ def viewer_hide_toolbar=(viewer_hide_toolbar)
1103
+ @parameters['viewer_hide_toolbar'] = viewer_hide_toolbar
1104
+ end
1105
+
1106
+ # Set a flag specifying whether to hide user interface elements in the document's window (such as scroll bars and navigation controls), leaving only the document's contents displayed.
1107
+ #
1108
+ # @param viewer_hide_window_ui Hide window UI or not.
1109
+ def viewer_hide_window_ui=(viewer_hide_window_ui)
1110
+ @parameters['viewer_hide_window_ui'] = viewer_hide_window_ui
1111
+ end
1112
+
1113
+ # Control if a custom header is displayed in the generated PDF document. The default value is False.
1114
+ #
1115
+ # @param show_header Show header or not.
1116
+ def show_header=(show_header)
1117
+ @parameters['show_header'] = show_header
1118
+ end
1119
+
1120
+ # The height of the pdf document header. This height is specified in points. 1 point is 1/72 inch. The default value is 50.
1121
+ #
1122
+ # @param header_height Header height.
1123
+ def header_height=(header_height)
1124
+ @parameters['header_height'] = header_height
1125
+ end
1126
+
1127
+ # Set the url of the web page that is converted and rendered in the PDF document header.
1128
+ #
1129
+ # @param header_url The url of the web page that is converted and rendered in the pdf document header.
1130
+ def header_url=(header_url)
1131
+ if !header_url.downcase.start_with?('http://') && !header_url.downcase.start_with?('https://')
1132
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
1133
+ end
1134
+
1135
+ if header_url.downcase.start_with?('http://localhost')
1136
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
1137
+ end
1138
+
1139
+ @parameters['header_url'] = header_url
1140
+ end
1141
+
1142
+ # Set the raw html that is converted and rendered in the pdf document header.
1143
+ #
1144
+ # @param header_html The raw html that is converted and rendered in the pdf document header.
1145
+ def header_html=(header_html)
1146
+ @parameters['header_html'] = header_html
1147
+ end
1148
+
1149
+ # Set an optional base url parameter can be used together with the header HTML to resolve relative paths from the html string.
1150
+ #
1151
+ # @param header_base_url Header base url.
1152
+ def header_base_url=(header_base_url)
1153
+ if !header_base_url.downcase.start_with?('http://') && !header_base_url.downcase.start_with?('https://')
1154
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
1155
+ end
1156
+
1157
+ if header_base_url.downcase.start_with?('http://localhost')
1158
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
1159
+ end
1160
+
1161
+ @parameters['header_base_url'] = header_base_url
1162
+ end
1163
+
1164
+ # Control the visibility of the header on the first page of the generated pdf document. The default value is True.
1165
+ #
1166
+ # @param header_display_on_first_page Display header on the first page or not.
1167
+ def header_display_on_first_page=(header_display_on_first_page)
1168
+ @parameters['header_display_on_first_page'] = header_display_on_first_page
1169
+ end
1170
+
1171
+ # Control the visibility of the header on the odd numbered pages of the generated pdf document. The default value is True.
1172
+ #
1173
+ # @param header_display_on_odd_pages Display header on odd pages or not.
1174
+ def header_display_on_odd_pages=(header_display_on_odd_pages)
1175
+ @parameters['header_display_on_odd_pages'] = header_display_on_odd_pages
1176
+ end
1177
+
1178
+ # Control the visibility of the header on the even numbered pages of the generated pdf document. The default value is True.
1179
+ #
1180
+ # @param header_display_on_even_pages Display header on even pages or not.
1181
+ def header_display_on_even_pages=(header_display_on_even_pages)
1182
+ @parameters['header_display_on_even_pages'] = header_display_on_even_pages
1183
+ end
1184
+
1185
+ # Set the width in pixels used by the converter's internal browser window during the conversion of the header content. The default value is 1024px.
1186
+ #
1187
+ # @param header_web_page_width Browser window width in pixels.
1188
+ def header_web_page_width=(header_web_page_width)
1189
+ @parameters['header_web_page_width'] = header_web_page_width
1190
+ end
1191
+
1192
+ # Set the height in pixels used by the converter's internal browser window during the conversion of the header content.
1193
+ # The default value is 0px and it means that the page height is automatically calculated by the converter.
1194
+ #
1195
+ # @param header_web_page_height Browser window height in pixels. Set it to 0px to automatically calculate page height.
1196
+ def header_web_page_height=(header_web_page_height)
1197
+ @parameters['header_web_page_height'] = header_web_page_height
1198
+ end
1199
+
1200
+ # Control if a custom footer is displayed in the generated PDF document. The default value is False.
1201
+ #
1202
+ # @param show_footer Show footer or not.
1203
+ def show_footer=(show_footer)
1204
+ @parameters['show_footer'] = show_footer
1205
+ end
1206
+
1207
+ # The height of the pdf document footer. This height is specified in points. 1 point is 1/72 inch. The default value is 50.
1208
+ #
1209
+ # @param footer_height Footer height.
1210
+ def footer_height=(footer_height)
1211
+ @parameters['footer_height'] = footer_height
1212
+ end
1213
+
1214
+ # Set the url of the web page that is converted and rendered in the PDF document footer.
1215
+ #
1216
+ # @param footer_url The url of the web page that is converted and rendered in the pdf document footer.
1217
+ def footer_url=(footer_url)
1218
+ if !footer_url.downcase.start_with?('http://') && !footer_url.downcase.start_with?('https://')
1219
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
1220
+ end
1221
+
1222
+ if footer_url.downcase.start_with?('http://localhost')
1223
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
1224
+ end
1225
+
1226
+ @parameters['footer_url'] = footer_url
1227
+ end
1228
+
1229
+ # Set the raw html that is converted and rendered in the pdf document footer.
1230
+ #
1231
+ # @param footer_html The raw html that is converted and rendered in the pdf document footer.
1232
+ def footer_html=(footer_html)
1233
+ @parameters['footer_html'] = footer_html
1234
+ end
1235
+
1236
+ # Set an optional base url parameter can be used together with the footer HTML to resolve relative paths from the html string.
1237
+ #
1238
+ # @param footer_base_url Footer base url.
1239
+ def footer_base_url=(footer_base_url)
1240
+ if !footer_base_url.downcase.start_with?('http://') && !footer_base_url.downcase.start_with?('https://')
1241
+ raise ApiException.new('The supported protocols for the converted webpage are http:// and https://.'), 'The supported protocols for the converted webpage are http:// and https://.'
1242
+ end
1243
+
1244
+ if footer_base_url.downcase.start_with?('http://localhost')
1245
+ raise ApiException.new('Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'), 'Cannot convert local urls. SelectPdf online API can only convert publicly available urls.'
1246
+ end
1247
+
1248
+ @parameters['footer_base_url'] = footer_base_url
1249
+ end
1250
+
1251
+ # Control the visibility of the footer on the first page of the generated pdf document. The default value is True.
1252
+ #
1253
+ # @param footer_display_on_first_page Display footer on the first page or not.
1254
+ def footer_display_on_first_page=(footer_display_on_first_page)
1255
+ @parameters['footer_display_on_first_page'] = footer_display_on_first_page
1256
+ end
1257
+
1258
+ # Control the visibility of the footer on the odd numbered pages of the generated pdf document. The default value is True.
1259
+ #
1260
+ # @param footer_display_on_odd_pages Display footer on odd pages or not.
1261
+ def footer_display_on_odd_pages=(footer_display_on_odd_pages)
1262
+ @parameters['footer_display_on_odd_pages'] = footer_display_on_odd_pages
1263
+ end
1264
+
1265
+ # Control the visibility of the footer on the even numbered pages of the generated pdf document. The default value is True.
1266
+ #
1267
+ # @param footer_display_on_even_pages Display footer on even pages or not.
1268
+ def footer_display_on_even_pages=(footer_display_on_even_pages)
1269
+ @parameters['footer_display_on_even_pages'] = footer_display_on_even_pages
1270
+ end
1271
+
1272
+ # Add a special footer on the last page of the generated pdf document only. The default value is False.
1273
+ # Use footer_url or footer_html and footer_base_url to specify the content of the last page footer.
1274
+ # Use footer_height to specify the height of the special last page footer.
1275
+ #
1276
+ # @param footer_display_on_last_page Display special footer on the last page or not.
1277
+ def footer_display_on_last_page=(footer_display_on_last_page)
1278
+ @parameters['footer_display_on_last_page'] = footer_display_on_last_page
1279
+ end
1280
+
1281
+ # Set the width in pixels used by the converter's internal browser window during the conversion of the footer content. The default value is 1024px.
1282
+ #
1283
+ # @param footer_web_page_width Browser window width in pixels.
1284
+ def footer_web_page_width=(footer_web_page_width)
1285
+ @parameters['footer_web_page_width'] = footer_web_page_width
1286
+ end
1287
+
1288
+ # Set the height in pixels used by the converter's internal browser window during the conversion of the footer content.
1289
+ # The default value is 0px and it means that the page height is automatically calculated by the converter.
1290
+ #
1291
+ # @param footer_web_page_height Browser window height in pixels. Set it to 0px to automatically calculate page height.
1292
+ def footer_web_page_height=(footer_web_page_height)
1293
+ @parameters['footer_web_page_height'] = footer_web_page_height
1294
+ end
1295
+
1296
+ # Show page numbers. Default value is True. Page numbers will be displayed in the footer of the PDF document.
1297
+ #
1298
+ # @param page_numbers Show page numbers or not.
1299
+ def page_numbers=(page_numbers)
1300
+ @parameters['page_numbers'] = page_numbers
1301
+ end
1302
+
1303
+ # Control the page number for the first page being rendered. The default value is 1.
1304
+ #
1305
+ # @param page_numbers_first First page number.
1306
+ def page_numbers_first=(page_numbers_first)
1307
+ @parameters['page_numbers_first'] = page_numbers_first
1308
+ end
1309
+
1310
+ # Control the total number of pages offset in the generated pdf document. The default value is 0.
1311
+ #
1312
+ # @param page_numbers_offset Offset for the total number of pages in the generated pdf document.
1313
+ def page_numbers_offset=(page_numbers_offset)
1314
+ @parameters['page_numbers_offset'] = page_numbers_offset
1315
+ end
1316
+
1317
+ # Set the text that is used to display the page numbers.
1318
+ # It can contain the placeholder \\{page_number} for the current page number and \\{total_pages} for the total number of pages.
1319
+ # The default value is "Page: \\{page_number} of \\{total_pages}".
1320
+ #
1321
+ # @param page_numbers_template Page numbers template.
1322
+ def page_numbers_template=(page_numbers_template)
1323
+ @parameters['page_numbers_template'] = page_numbers_template
1324
+ end
1325
+
1326
+ # Set the font used to display the page numbers text. The default value is "Helvetica".
1327
+ #
1328
+ # @param page_numbers_font_name The font used to display the page numbers text.
1329
+ def page_numbers_font_name=(page_numbers_font_name)
1330
+ @parameters['page_numbers_font_name'] = page_numbers_font_name
1331
+ end
1332
+
1333
+ # Set the size of the font used to display the page numbers. The default value is 10 points.
1334
+ #
1335
+ # @param page_numbers_font_size The size in points of the font used to display the page numbers.
1336
+ def page_numbers_font_size=(page_numbers_font_size)
1337
+ @parameters['page_numbers_font_size'] = page_numbers_font_size
1338
+ end
1339
+
1340
+ # Set the alignment of the page numbers text. The default value is SelectPdf::PageNumbersAlignment::RIGHT.
1341
+ #
1342
+ # @param page_numbers_alignment The alignment of the page numbers text.
1343
+ def page_numbers_alignment=(page_numbers_alignment)
1344
+ unless [1, 2, 3].include?(page_numbers_alignment)
1345
+ raise ApiException.new('Allowed values for Page Numbers Alignment: 1 (Left), 2 (Center), 3 (Right).'),
1346
+ 'Allowed values for Page Numbers Alignment: 1 (Left), 2 (Center), 3 (Right).'
1347
+ end
1348
+
1349
+ @parameters['page_numbers_alignment'] = page_numbers_alignment
1350
+ end
1351
+
1352
+ # Specify the color of the page numbers text in #RRGGBB html format. The default value is #333333.
1353
+ #
1354
+ # @param page_numbers_color Page numbers color.
1355
+ def page_numbers_color=(page_numbers_color)
1356
+ unless /^#?[0-9a-fA-F]{6}$/.match(page_numbers_color)
1357
+ raise ApiException.new('Color value must be in #RRGGBB format.'), 'Color value must be in #RRGGBB format.'
1358
+ end
1359
+
1360
+ @parameters['page_numbers_color'] = page_numbers_color
1361
+ end
1362
+
1363
+ # Specify the position in points on the vertical where the page numbers text is displayed in the footer. The default value is 10 points.
1364
+ #
1365
+ # @param page_numbers_pos_y Page numbers Y position in points.
1366
+ def page_numbers_pos_y=(page_numbers_pos_y)
1367
+ @parameters['page_numbers_pos_y'] = page_numbers_pos_y
1368
+ end
1369
+
1370
+ # Generate automatic bookmarks in pdf. The elements that will be bookmarked are defined using CSS selectors.
1371
+ # For example, the selector for all the H1 elements is "H1", the selector for all the elements with the CSS class name 'myclass' is "*.myclass" and
1372
+ # the selector for the elements with the id 'myid' is "*#myid". Read more about CSS selectors <a href="http://www.w3schools.com/cssref/css_selectors.asp" target="_blank">here</a>.
1373
+ #
1374
+ # @param pdf_bookmarks_selectors CSS selectors used to identify HTML elements, comma separated.
1375
+ def pdf_bookmarks_selectors=(pdf_bookmarks_selectors)
1376
+ @parameters['pdf_bookmarks_selectors'] = pdf_bookmarks_selectors
1377
+ end
1378
+
1379
+ # Exclude page elements from the conversion. The elements that will be excluded are defined using CSS selectors.
1380
+ # For example, the selector for all the H1 elements is "H1", the selector for all the elements with the CSS class name 'myclass' is "*.myclass" and
1381
+ # the selector for the elements with the id 'myid' is "*#myid". Read more about CSS selectors <a href="http://www.w3schools.com/cssref/css_selectors.asp" target="_blank">here</a>.
1382
+ #
1383
+ # @param pdf_hide_elements CSS selectors used to identify HTML elements, comma separated.
1384
+ def pdf_hide_elements=(pdf_hide_elements)
1385
+ @parameters['pdf_hide_elements'] = pdf_hide_elements
1386
+ end
1387
+
1388
+ # Convert only a specific section of the web page to pdf.
1389
+ # The section that will be converted to pdf is specified by the html element ID.
1390
+ # The element can be anything (image, table, table row, div, text, etc).
1391
+ #
1392
+ # @param pdf_show_only_element_id HTML element ID.
1393
+ def pdf_show_only_element_id=(pdf_show_only_element_id)
1394
+ @parameters['pdf_show_only_element_id'] = pdf_show_only_element_id
1395
+ end
1396
+
1397
+ # Get the locations of page elements from the conversion. The elements that will have their locations retrieved are defined using CSS selectors.
1398
+ # For example, the selector for all the H1 elements is "H1", the selector for all the elements with the CSS class name 'myclass' is "*.myclass" and
1399
+ # the selector for the elements with the id 'myid' is "*#myid". Read more about CSS selectors <a href="http://www.w3schools.com/cssref/css_selectors.asp" target="_blank">here</a>.
1400
+ #
1401
+ # @param pdf_web_elements_selectors CSS selectors used to identify HTML elements, comma separated.
1402
+ def pdf_web_elements_selectors=(pdf_web_elements_selectors)
1403
+ @parameters['pdf_web_elements_selectors'] = pdf_web_elements_selectors
1404
+ end
1405
+
1406
+ # Set converter startup mode. The default value is SelectPdf::StartupMode::AUTOMATIC and the conversion is started immediately.
1407
+ # By default this is set to SelectPdf::StartupMode::AUTOMATIC and the conversion is started as soon as the page loads (and conversion delay set with conversion_delay elapses).
1408
+ # If set to SelectPdf::StartupMode::MANUAL, the conversion is started only by a javascript call to SelectPdf.startConversion() from within the web page.
1409
+ #
1410
+ # @param startup_mode Converter startup mode.
1411
+ def startup_mode=(startup_mode)
1412
+ unless /(?i)^(Automatic|Manual)$/.match(startup_mode)
1413
+ raise ApiException.new('Allowed values for Startup Mode: Automatic, Manual.'), 'Allowed values for Startup Mode: Automatic, Manual.'
1414
+ end
1415
+
1416
+ @parameters['startup_mode'] = startup_mode
1417
+ end
1418
+
1419
+ # Internal use only.
1420
+ #
1421
+ # @param skip_decoding The default value is True.
1422
+ def skip_decoding=(skip_decoding)
1423
+ @parameters['skip_decoding'] = skip_decoding
1424
+ end
1425
+
1426
+ # Set a flag indicating if the images from the page are scaled during the conversion process. The default value is False and images are not scaled.
1427
+ #
1428
+ # @param scale_images Scale images or not.
1429
+ def scale_images=(scale_images)
1430
+ @parameters['scale_images'] = scale_images
1431
+ end
1432
+
1433
+ # Generate a single page PDF. The converter will automatically resize the PDF page to fit all the content in a single page.
1434
+ # The default value of this property is False and the PDF will contain several pages if the content is large.
1435
+ #
1436
+ # @param single_page_pdf Generate a single page PDF or not.
1437
+ def single_page_pdf=(single_page_pdf)
1438
+ @parameters['single_page_pdf'] = single_page_pdf
1439
+ end
1440
+
1441
+ # Get or set a flag indicating if an enhanced custom page breaks algorithm is used.
1442
+ # The enhanced algorithm is a little bit slower but it will prevent the appearance of hidden text in the PDF when custom page breaks are used.
1443
+ # The default value for this property is False.
1444
+ #
1445
+ # @param page_breaks_enhanced_algorithm Enable enhanced page breaks algorithm or not.
1446
+ def page_breaks_enhanced_algorithm=(page_breaks_enhanced_algorithm)
1447
+ @parameters['page_breaks_enhanced_algorithm'] = page_breaks_enhanced_algorithm
1448
+ end
1449
+
1450
+ # Set HTTP cookies for the web page being converted.
1451
+ #
1452
+ # @param cookies HTTP cookies that will be sent to the page being converted.
1453
+ def cookies=(cookies)
1454
+ @parameters['cookies_string'] = URI.encode_www_form(cookies)
1455
+ end
1456
+
1457
+ # Set a custom parameter. Do not use this method unless advised by SelectPdf.
1458
+ #
1459
+ # @param parameter_name Parameter name.
1460
+ # @param parameter_value Parameter value.
1461
+ def set_custom_parameter(parameter_name, parameter_value)
1462
+ @parameters[parameter_name] = parameter_value
1463
+ end
1464
+
1465
+ # Get the locations of certain web elements. This is retrieved if pdf_web_elements_selectors parameter is set and elements were found to match the selectors.
1466
+ #
1467
+ # @return List of web elements locations.
1468
+ def web_elements
1469
+ web_elements_client = WebElementsClient.new(@parameters['key'], @job_id)
1470
+ web_elements_client.api_endpoint = @api_web_elements_endpoint
1471
+
1472
+ web_elements_client.web_elements
1473
+ end
1474
+ end
1475
+
1476
+ # Get the locations of certain web elements.
1477
+ # This is retrieved if pdf_web_elements_selectors parameter was set during the initial conversion call and elements were found to match the selectors.
1478
+ class WebElementsClient < ApiClient
1479
+ # Construct the web elements client.
1480
+ #
1481
+ # @param api_key API Key.
1482
+ # @param job_id Job ID.
1483
+ def initialize(api_key, job_id)
1484
+ super()
1485
+ @api_endpoint = 'https://selectpdf.com/api2/webelements/'
1486
+ @parameters['key'] = api_key
1487
+ @parameters['job_id'] = job_id
1488
+ end
1489
+
1490
+ # Get the locations of certain web elements.
1491
+ # This is retrieved if pdf_web_elements_selectors parameter is set and elements were found to match the selectors.
1492
+ #
1493
+ # @return List of web elements locations.
1494
+ def web_elements
1495
+ @headers['Accept'] = 'text/json'
1496
+
1497
+ result = perform_post
1498
+ return JSON.parse(result) unless result.nil? || result.empty?
1499
+
1500
+ []
1501
+ end
1502
+ end
1503
+
1504
+ # Get the result of an asynchronous call.
1505
+ class AsyncJobClient < ApiClient
1506
+ # Construct the async job client.
1507
+ #
1508
+ # @param api_key API Key.
1509
+ # @param job_id Job ID.
1510
+ def initialize(api_key, job_id)
1511
+ super()
1512
+ @api_endpoint = 'https://selectpdf.com/api2/asyncjob/'
1513
+ @parameters['key'] = api_key
1514
+ @parameters['job_id'] = job_id
1515
+ end
1516
+
1517
+ # Get result of the asynchronous job.
1518
+ #
1519
+ # @return Byte array containing the resulted file if the job is finished. Returns nil if the job is still running. Throws an exception if an error occurred.
1520
+ def result
1521
+ result = perform_post
1522
+
1523
+ return result if @job_id.nil? || @job_id.empty?
1524
+
1525
+ return nil
1526
+ end
1527
+ end
1528
+ end