diff --git a/.docker_env.list b/.docker_env.list index 291bd70..f79b976 100644 --- a/.docker_env.list +++ b/.docker_env.list @@ -1,2 +1,3 @@ TRACE TEST_OUTPUT_DIR=/app/tmp/test_output +INSIDE_DOCKER=true diff --git a/.docker_mounts.list b/.docker_mounts.list new file mode 100644 index 0000000..e6d449e --- /dev/null +++ b/.docker_mounts.list @@ -0,0 +1,4 @@ +# Specify mounts in `docker run --volume` format (source:target). Bash +# expressions will be evaluated. +# $(pwd)/tmp/cache_${image//:/_}:/app/tmp/cache +${HOME}/.gnupg/docraptor:/root/.gnupg_host_docraptor diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index f391b91..eb1e4dc 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -23,16 +23,6 @@ #!docs/README.md -# These are autogenerated and aren't exactly what we want. We rely on the -# readme, and website documentation. -# TODO: Ideally, when updating the agent, it would be nice to see the -# differences between when the previous version and the new version generated. -# This would help make it more obvious when the agent supported a newer usage -# pattern that we might prefer. -# TODO: Consider if it's possible to make the generated docs more useful so we -# might actually want to use them. -docs/ - # This seems to be a script related to developing openapi-generator and making # new test APIs. git_push.sh diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index bf233dd..77a720c 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -5,6 +5,11 @@ README.md api/openapi.yaml build.gradle build.sbt +docs/AsyncDoc.md +docs/Doc.md +docs/DocApi.md +docs/DocStatus.md +docs/PrinceOptions.md gradle.properties gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.properties diff --git a/.review/generated_files/README.md b/.review/generated_files/README.md index 8453a81..edf800a 100644 --- a/.review/generated_files/README.md +++ b/.review/generated_files/README.md @@ -40,7 +40,7 @@ Add this dependency to your project's POM: com.docraptor docraptor - 2.0.0 + 3.2.0 compile ``` @@ -56,7 +56,7 @@ Add this dependency to your project's build file: } dependencies { - implementation "com.docraptor:docraptor:2.0.0" + implementation "com.docraptor:docraptor:3.2.0" } ``` @@ -70,7 +70,7 @@ mvn clean package Then manually install the following JARs: -- `target/docraptor-2.0.0.jar` +- `target/docraptor-3.2.0.jar` - `target/lib/*.jar` ## Getting Started diff --git a/.review/generated_files/docs/AsyncDoc.md b/.review/generated_files/docs/AsyncDoc.md new file mode 100644 index 0000000..d35681e --- /dev/null +++ b/.review/generated_files/docs/AsyncDoc.md @@ -0,0 +1,13 @@ + + +# AsyncDoc + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**statusId** | **String** | The identifier used to get the status of the document using the status API. | [optional] | + + + diff --git a/.review/generated_files/docs/Doc.md b/.review/generated_files/docs/Doc.md new file mode 100644 index 0000000..529e54a --- /dev/null +++ b/.review/generated_files/docs/Doc.md @@ -0,0 +1,49 @@ + + +# Doc + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**name** | **String** | A name for identifying your document. | | +|**documentType** | [**DocumentTypeEnum**](#DocumentTypeEnum) | The type of document being created. | | +|**documentContent** | **String** | The HTML data to be transformed into a document. You must supply content using document_content or document_url. | | +|**documentUrl** | **String** | The URL to fetch the HTML data to be transformed into a document. You must supply content using document_content or document_url. | [optional] | +|**test** | **Boolean** | Enable test mode for this document. Test documents are not charged for but include a watermark. | [optional] | +|**pipeline** | **String** | Specify a specific verison of the DocRaptor Pipeline to use. | [optional] | +|**strict** | [**StrictEnum**](#StrictEnum) | Force strict HTML validation. | [optional] | +|**ignoreResourceErrors** | **Boolean** | Failed loading of images/javascripts/stylesheets/etc. will not cause the rendering to stop. | [optional] | +|**ignoreConsoleMessages** | **Boolean** | Prevent console.log from stopping document rendering during JavaScript execution. | [optional] | +|**tag** | **String** | A field for storing a small amount of metadata with this document. | [optional] | +|**help** | **Boolean** | Request support help with this request if it succeeds. | [optional] | +|**javascript** | **Boolean** | Enable DocRaptor JavaScript parsing. PrinceXML JavaScript parsing is also available elsewhere. | [optional] | +|**referrer** | **String** | Set HTTP referrer when generating this document. | [optional] | +|**callbackUrl** | **String** | A URL that will receive a POST request after successfully completing an asynchronous document. The POST data will include download_url and download_id similar to status API responses. WARNING: this only works on asynchronous documents. | [optional] | +|**hostedDownloadLimit** | **Integer** | The number of times a hosted document can be downloaded. If no limit is specified, the document will be available for an unlimited number of downloads. | [optional] | +|**hostedExpiresAt** | **String** | The date and time at which a hosted document will be removed and no longer available. Must be a properly formatted ISO 8601 datetime, like 1981-01-23T08:02:30-05:00. | [optional] | +|**princeOptions** | [**PrinceOptions**](PrinceOptions.md) | | [optional] | +|**userAgentToken** | **String** | A token that will be added to the user agent for all requests made for document content while creating a PDF. | [optional] | + + + +## Enum: DocumentTypeEnum + +| Name | Value | +|---- | -----| +| PDF | "pdf" | +| XLS | "xls" | +| XLSX | "xlsx" | + + + +## Enum: StrictEnum + +| Name | Value | +|---- | -----| +| NONE | "none" | +| HTML | "html" | + + + diff --git a/.review/generated_files/docs/DocApi.md b/.review/generated_files/docs/DocApi.md new file mode 100644 index 0000000..833e544 --- /dev/null +++ b/.review/generated_files/docs/DocApi.md @@ -0,0 +1,547 @@ +# DocApi + +All URIs are relative to *https://api.docraptor.com* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**createAsyncDoc**](DocApi.md#createAsyncDoc) | **POST** /async_docs | | +| [**createDoc**](DocApi.md#createDoc) | **POST** /docs | | +| [**createHostedAsyncDoc**](DocApi.md#createHostedAsyncDoc) | **POST** /hosted_async_docs | | +| [**createHostedDoc**](DocApi.md#createHostedDoc) | **POST** /hosted_docs | | +| [**expire**](DocApi.md#expire) | **PATCH** /expire/{id} | | +| [**getAsyncDoc**](DocApi.md#getAsyncDoc) | **GET** /download/{id} | | +| [**getAsyncDocStatus**](DocApi.md#getAsyncDocStatus) | **GET** /status/{id} | | + + + +## createAsyncDoc + +> AsyncDoc createAsyncDoc(doc) + + + +Creates a document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + AsyncDoc result = apiInstance.createAsyncDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createAsyncDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +[**AsyncDoc**](AsyncDoc.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## createDoc + +> byte[] createDoc(doc) + + + +Creates a document synchronously. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + byte[] result = apiInstance.createDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +**byte[]** + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## createHostedAsyncDoc + +> AsyncDoc createHostedAsyncDoc(doc) + + + +Creates a hosted document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + AsyncDoc result = apiInstance.createHostedAsyncDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createHostedAsyncDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +[**AsyncDoc**](AsyncDoc.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## createHostedDoc + +> DocStatus createHostedDoc(doc) + + + +Creates a hosted document synchronously. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + Doc doc = new Doc(); // Doc | The document to be created. + try { + DocStatus result = apiInstance.createHostedDoc(doc); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#createHostedDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **doc** | [**Doc**](Doc.md)| The document to be created. | | + +### Return type + +[**DocStatus**](DocStatus.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **422** | Unprocessable Entity | - | +| **500** | Server Error | - | + + +## expire + +> expire(id) + + + +Expires a previously created hosted doc. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + String id = "id_example"; // String | The download_id returned from status request or hosted document response. + try { + apiInstance.expire(id); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#expire"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| The download_id returned from status request or hosted document response. | | + +### Return type + +null (empty response body) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **500** | Server Error | - | + + +## getAsyncDoc + +> byte[] getAsyncDoc(id) + + + +Downloads a finished document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + String id = "id_example"; // String | The download_id returned from an async status request or callback. + try { + byte[] result = apiInstance.getAsyncDoc(id); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#getAsyncDoc"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| The download_id returned from an async status request or callback. | | + +### Return type + +**byte[]** + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **400** | Bad Request | - | +| **403** | Forbidden | - | +| **500** | Server Error | - | + + +## getAsyncDocStatus + +> DocStatus getAsyncDocStatus(id) + + + +Check on the status of an asynchronously created document. + +### Example + +```java +// Import classes: +import com.docraptor.ApiClient; +import com.docraptor.ApiException; +import com.docraptor.Configuration; +import com.docraptor.auth.*; +import com.docraptor.models.*; +import com.docraptor.DocApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://api.docraptor.com"); + + // Configure HTTP basic authorization: basicAuth + HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("basicAuth"); + basicAuth.setUsername("YOUR USERNAME"); + basicAuth.setPassword("YOUR PASSWORD"); + + DocApi apiInstance = new DocApi(defaultClient); + String id = "id_example"; // String | The status_id returned when creating an asynchronous document. + try { + DocStatus result = apiInstance.getAsyncDocStatus(id); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DocApi#getAsyncDocStatus"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| The status_id returned when creating an asynchronous document. | | + +### Return type + +[**DocStatus**](DocStatus.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json, application/xml, application/pdf, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Successful response | - | +| **401** | Unauthorized | - | +| **403** | Forbidden | - | +| **500** | Server Error | - | + diff --git a/.review/generated_files/docs/DocStatus.md b/.review/generated_files/docs/DocStatus.md new file mode 100644 index 0000000..c13a64c --- /dev/null +++ b/.review/generated_files/docs/DocStatus.md @@ -0,0 +1,18 @@ + + +# DocStatus + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**status** | **String** | The present status of the document. Can be queued, working, completed, and failed. | [optional] | +|**downloadUrl** | **String** | The URL where the document can be retrieved. This URL may only be used a few times. | [optional] | +|**downloadId** | **String** | The identifier for downloading the document with the download API. | [optional] | +|**message** | **String** | Additional information. | [optional] | +|**numberOfPages** | **Integer** | Number of PDF pages in document. | [optional] | +|**validationErrors** | **String** | Error information. | [optional] | + + + diff --git a/.review/generated_files/docs/PrinceOptions.md b/.review/generated_files/docs/PrinceOptions.md new file mode 100644 index 0000000..176719b --- /dev/null +++ b/.review/generated_files/docs/PrinceOptions.md @@ -0,0 +1,55 @@ + + +# PrinceOptions + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**baseurl** | **String** | Set the baseurl for assets. | [optional] | +|**noXinclude** | **Boolean** | Disable XML inclusion. | [optional] | +|**noNetwork** | **Boolean** | Disable network access. | [optional] | +|**noParallelDownloads** | **Boolean** | Disables parallel fetching of assets during PDF creation. Useful if your asset host has strict rate limiting. | [optional] | +|**httpUser** | **String** | Set the user for HTTP authentication. | [optional] | +|**httpPassword** | **String** | Set the password for HTTP authentication. | [optional] | +|**httpProxy** | **String** | Set the HTTP proxy server. | [optional] | +|**httpTimeout** | **Integer** | Set the HTTP request timeout. | [optional] | +|**insecure** | **Boolean** | Disable SSL verification. | [optional] | +|**media** | **String** | Specify the CSS media type. Defaults to \"print\" but you may want to use \"screen\" for web styles. | [optional] | +|**noAuthorStyle** | **Boolean** | Ignore author stylesheets. | [optional] | +|**noDefaultStyle** | **Boolean** | Ignore default stylesheets. | [optional] | +|**noEmbedFonts** | **Boolean** | Disable font embedding in PDFs. | [optional] | +|**noSubsetFonts** | **Boolean** | Disable font subsetting in PDFs. | [optional] | +|**noCompress** | **Boolean** | Disable PDF compression. | [optional] | +|**encrypt** | **Boolean** | Encrypt PDF output. | [optional] | +|**keyBits** | **Integer** | Set encryption key size. | [optional] | +|**userPassword** | **String** | Set the PDF user password. | [optional] | +|**ownerPassword** | **String** | Set the PDF owner password. | [optional] | +|**disallowPrint** | **Boolean** | Disallow printing of this PDF. | [optional] | +|**disallowCopy** | **Boolean** | Disallow copying of this PDF. | [optional] | +|**disallowAnnotate** | **Boolean** | Disallow annotation of this PDF. | [optional] | +|**disallowModify** | **Boolean** | Disallow modification of this PDF. | [optional] | +|**debug** | **Boolean** | Enable Prince debug mode. | [optional] | +|**input** | [**InputEnum**](#InputEnum) | Specify the input format. | [optional] | +|**version** | **String** | Deprecated, use the appropriate `pipeline` version. Specify a specific verison of PrinceXML to use. | [optional] | +|**javascript** | **Boolean** | Enable PrinceXML JavaScript. DocRaptor JavaScript parsing is also available elsewhere. | [optional] | +|**cssDpi** | **Integer** | Set the DPI when rendering CSS. Defaults to 96 but can be set with Prince 9.0 and up. | [optional] | +|**profile** | **String** | In Prince 9.0 and up you can set the PDF profile. | [optional] | +|**pdfTitle** | **String** | Specify the PDF title, part of the document's metadata. | [optional] | +|**iframes** | **Boolean** | Enable loading of iframes. | [optional] | +|**pageMargin** | **String** | Specify the page margin distance. | [optional] | +|**pdfForms** | **Boolean** | Make form fields editable by default. | [optional] | + + + +## Enum: InputEnum + +| Name | Value | +|---- | -----| +| HTML | "html" | +| XML | "xml" | +| AUTO | "auto" | + + + diff --git a/.review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java b/.review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java new file mode 100644 index 0000000..f725cf2 --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/AsyncDocTest.java @@ -0,0 +1,50 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for AsyncDoc + */ +public class AsyncDocTest { + private final AsyncDoc model = new AsyncDoc(); + + /** + * Model tests for AsyncDoc + */ + @Test + public void testAsyncDoc() { + // TODO: test AsyncDoc + } + + /** + * Test the property 'statusId' + */ + @Test + public void statusIdTest() { + // TODO: test statusId + } + +} diff --git a/.review/generated_files/src/test/java/com/docraptor/DocApiTest.java b/.review/generated_files/src/test/java/com/docraptor/DocApiTest.java new file mode 100644 index 0000000..556c7ed --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/DocApiTest.java @@ -0,0 +1,143 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.docraptor.ApiException; +import com.docraptor.AsyncDoc; +import com.docraptor.Doc; +import com.docraptor.DocStatus; +import org.junit.Test; +import org.junit.Ignore; +import org.junit.Assert; + +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * API tests for DocApi + */ +public class DocApiTest { + + private final DocApi api = new DocApi(); + + /** + * Creates a document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createAsyncDocTest() throws ApiException { + // + //Doc doc = null; + // + //AsyncDoc response = api.createAsyncDoc(doc); + + // TODO: test validations + } + /** + * Creates a document synchronously. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createDocTest() throws ApiException { + // + //Doc doc = null; + // + //byte[] response = api.createDoc(doc); + + // TODO: test validations + } + /** + * Creates a hosted document asynchronously. You must use a callback url or the returned status id and the status API to find out when it completes. Then use the download API to get the document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createHostedAsyncDocTest() throws ApiException { + // + //Doc doc = null; + // + //AsyncDoc response = api.createHostedAsyncDoc(doc); + + // TODO: test validations + } + /** + * Creates a hosted document synchronously. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void createHostedDocTest() throws ApiException { + // + //Doc doc = null; + // + //DocStatus response = api.createHostedDoc(doc); + + // TODO: test validations + } + /** + * Expires a previously created hosted doc. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void expireTest() throws ApiException { + // + //String id = null; + // + //api.expire(id); + + // TODO: test validations + } + /** + * Downloads a finished document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void getAsyncDocTest() throws ApiException { + // + //String id = null; + // + //byte[] response = api.getAsyncDoc(id); + + // TODO: test validations + } + /** + * Check on the status of an asynchronously created document. + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void getAsyncDocStatusTest() throws ApiException { + // + //String id = null; + // + //DocStatus response = api.getAsyncDocStatus(id); + + // TODO: test validations + } +} diff --git a/.review/generated_files/src/test/java/com/docraptor/DocStatusTest.java b/.review/generated_files/src/test/java/com/docraptor/DocStatusTest.java new file mode 100644 index 0000000..1ac08c5 --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/DocStatusTest.java @@ -0,0 +1,90 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for DocStatus + */ +public class DocStatusTest { + private final DocStatus model = new DocStatus(); + + /** + * Model tests for DocStatus + */ + @Test + public void testDocStatus() { + // TODO: test DocStatus + } + + /** + * Test the property 'status' + */ + @Test + public void statusTest() { + // TODO: test status + } + + /** + * Test the property 'downloadUrl' + */ + @Test + public void downloadUrlTest() { + // TODO: test downloadUrl + } + + /** + * Test the property 'downloadId' + */ + @Test + public void downloadIdTest() { + // TODO: test downloadId + } + + /** + * Test the property 'message' + */ + @Test + public void messageTest() { + // TODO: test message + } + + /** + * Test the property 'numberOfPages' + */ + @Test + public void numberOfPagesTest() { + // TODO: test numberOfPages + } + + /** + * Test the property 'validationErrors' + */ + @Test + public void validationErrorsTest() { + // TODO: test validationErrors + } + +} diff --git a/.review/generated_files/src/test/java/com/docraptor/DocTest.java b/.review/generated_files/src/test/java/com/docraptor/DocTest.java new file mode 100644 index 0000000..6722034 --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/DocTest.java @@ -0,0 +1,187 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.docraptor.PrinceOptions; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for Doc + */ +public class DocTest { + private final Doc model = new Doc(); + + /** + * Model tests for Doc + */ + @Test + public void testDoc() { + // TODO: test Doc + } + + /** + * Test the property 'name' + */ + @Test + public void nameTest() { + // TODO: test name + } + + /** + * Test the property 'documentType' + */ + @Test + public void documentTypeTest() { + // TODO: test documentType + } + + /** + * Test the property 'documentContent' + */ + @Test + public void documentContentTest() { + // TODO: test documentContent + } + + /** + * Test the property 'documentUrl' + */ + @Test + public void documentUrlTest() { + // TODO: test documentUrl + } + + /** + * Test the property 'test' + */ + @Test + public void testTest() { + // TODO: test test + } + + /** + * Test the property 'pipeline' + */ + @Test + public void pipelineTest() { + // TODO: test pipeline + } + + /** + * Test the property 'strict' + */ + @Test + public void strictTest() { + // TODO: test strict + } + + /** + * Test the property 'ignoreResourceErrors' + */ + @Test + public void ignoreResourceErrorsTest() { + // TODO: test ignoreResourceErrors + } + + /** + * Test the property 'ignoreConsoleMessages' + */ + @Test + public void ignoreConsoleMessagesTest() { + // TODO: test ignoreConsoleMessages + } + + /** + * Test the property 'tag' + */ + @Test + public void tagTest() { + // TODO: test tag + } + + /** + * Test the property 'help' + */ + @Test + public void helpTest() { + // TODO: test help + } + + /** + * Test the property 'javascript' + */ + @Test + public void javascriptTest() { + // TODO: test javascript + } + + /** + * Test the property 'referrer' + */ + @Test + public void referrerTest() { + // TODO: test referrer + } + + /** + * Test the property 'callbackUrl' + */ + @Test + public void callbackUrlTest() { + // TODO: test callbackUrl + } + + /** + * Test the property 'hostedDownloadLimit' + */ + @Test + public void hostedDownloadLimitTest() { + // TODO: test hostedDownloadLimit + } + + /** + * Test the property 'hostedExpiresAt' + */ + @Test + public void hostedExpiresAtTest() { + // TODO: test hostedExpiresAt + } + + /** + * Test the property 'princeOptions' + */ + @Test + public void princeOptionsTest() { + // TODO: test princeOptions + } + + /** + * Test the property 'userAgentToken' + */ + @Test + public void userAgentTokenTest() { + // TODO: test userAgentToken + } + +} diff --git a/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java b/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java new file mode 100644 index 0000000..979c6a6 --- /dev/null +++ b/.review/generated_files/src/test/java/com/docraptor/PrinceOptionsTest.java @@ -0,0 +1,306 @@ +/* + * DocRaptor + * A native client library for the DocRaptor HTML to PDF/XLS service. + * + * The version of the OpenAPI document: 2.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.docraptor; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for PrinceOptions + */ +public class PrinceOptionsTest { + private final PrinceOptions model = new PrinceOptions(); + + /** + * Model tests for PrinceOptions + */ + @Test + public void testPrinceOptions() { + // TODO: test PrinceOptions + } + + /** + * Test the property 'baseurl' + */ + @Test + public void baseurlTest() { + // TODO: test baseurl + } + + /** + * Test the property 'noXinclude' + */ + @Test + public void noXincludeTest() { + // TODO: test noXinclude + } + + /** + * Test the property 'noNetwork' + */ + @Test + public void noNetworkTest() { + // TODO: test noNetwork + } + + /** + * Test the property 'noParallelDownloads' + */ + @Test + public void noParallelDownloadsTest() { + // TODO: test noParallelDownloads + } + + /** + * Test the property 'httpUser' + */ + @Test + public void httpUserTest() { + // TODO: test httpUser + } + + /** + * Test the property 'httpPassword' + */ + @Test + public void httpPasswordTest() { + // TODO: test httpPassword + } + + /** + * Test the property 'httpProxy' + */ + @Test + public void httpProxyTest() { + // TODO: test httpProxy + } + + /** + * Test the property 'httpTimeout' + */ + @Test + public void httpTimeoutTest() { + // TODO: test httpTimeout + } + + /** + * Test the property 'insecure' + */ + @Test + public void insecureTest() { + // TODO: test insecure + } + + /** + * Test the property 'media' + */ + @Test + public void mediaTest() { + // TODO: test media + } + + /** + * Test the property 'noAuthorStyle' + */ + @Test + public void noAuthorStyleTest() { + // TODO: test noAuthorStyle + } + + /** + * Test the property 'noDefaultStyle' + */ + @Test + public void noDefaultStyleTest() { + // TODO: test noDefaultStyle + } + + /** + * Test the property 'noEmbedFonts' + */ + @Test + public void noEmbedFontsTest() { + // TODO: test noEmbedFonts + } + + /** + * Test the property 'noSubsetFonts' + */ + @Test + public void noSubsetFontsTest() { + // TODO: test noSubsetFonts + } + + /** + * Test the property 'noCompress' + */ + @Test + public void noCompressTest() { + // TODO: test noCompress + } + + /** + * Test the property 'encrypt' + */ + @Test + public void encryptTest() { + // TODO: test encrypt + } + + /** + * Test the property 'keyBits' + */ + @Test + public void keyBitsTest() { + // TODO: test keyBits + } + + /** + * Test the property 'userPassword' + */ + @Test + public void userPasswordTest() { + // TODO: test userPassword + } + + /** + * Test the property 'ownerPassword' + */ + @Test + public void ownerPasswordTest() { + // TODO: test ownerPassword + } + + /** + * Test the property 'disallowPrint' + */ + @Test + public void disallowPrintTest() { + // TODO: test disallowPrint + } + + /** + * Test the property 'disallowCopy' + */ + @Test + public void disallowCopyTest() { + // TODO: test disallowCopy + } + + /** + * Test the property 'disallowAnnotate' + */ + @Test + public void disallowAnnotateTest() { + // TODO: test disallowAnnotate + } + + /** + * Test the property 'disallowModify' + */ + @Test + public void disallowModifyTest() { + // TODO: test disallowModify + } + + /** + * Test the property 'debug' + */ + @Test + public void debugTest() { + // TODO: test debug + } + + /** + * Test the property 'input' + */ + @Test + public void inputTest() { + // TODO: test input + } + + /** + * Test the property 'version' + */ + @Test + public void versionTest() { + // TODO: test version + } + + /** + * Test the property 'javascript' + */ + @Test + public void javascriptTest() { + // TODO: test javascript + } + + /** + * Test the property 'cssDpi' + */ + @Test + public void cssDpiTest() { + // TODO: test cssDpi + } + + /** + * Test the property 'profile' + */ + @Test + public void profileTest() { + // TODO: test profile + } + + /** + * Test the property 'pdfTitle' + */ + @Test + public void pdfTitleTest() { + // TODO: test pdfTitle + } + + /** + * Test the property 'iframes' + */ + @Test + public void iframesTest() { + // TODO: test iframes + } + + /** + * Test the property 'pageMargin' + */ + @Test + public void pageMarginTest() { + // TODO: test pageMargin + } + + /** + * Test the property 'pdfForms' + */ + @Test + public void pdfFormsTest() { + // TODO: test pdfForms + } + +} diff --git a/.runtime-environments b/.runtime-environments index b39cc24..9bfb83b 100644 --- a/.runtime-environments +++ b/.runtime-environments @@ -9,6 +9,9 @@ maven:3.8.6-eclipse-temurin maven:3.8.6-eclipse-temurin-19 maven:3.8.6-eclipse-temurin-17 maven:3.8.6-eclipse-temurin-11 -maven:3-jdk-10 -maven:3-jdk-9 maven:3.8.6-eclipse-temurin-8-focal + +# These are EOL and debian rotated apt keys, so `apt update` will fail. Leaving +# these commented so it's obvious why they're missing in the future. +# maven:3-jdk-10 +# maven:3-jdk-9 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9680413..c4f8d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -### 3.0.0 [TBD] +### 3.2.0 [April 2, 2024] +* Add the new userAgentToken API option, to enable passing a key that will be passed back on resource requests + +### 3.1.0 [July 14, 2023] +* Add new API options (including prince_options[pdf_forms] to enable PDF forms) + +### 3.0.0 [November 15, 2022] * Switch API host to more secure api.docraptor.com (dropping old TLS) * Switch from swagger to openapi-generator v6.0.1 (better maintained) * Remove support for java <8 diff --git a/README.md b/README.md index e87376a..814e786 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ After the client library is installed/deployed, you can use it in your Maven pro com.docraptor docraptor - 2.0.0 + 3.2.0 ``` @@ -109,13 +109,10 @@ If you haven't released before, please see the [release setup guide](RELEASE_SET 7. Commit "Release vX.Y.Z" 8. Push to GitHub 9. Tag version: `git tag 'vX.Y.Z' && git push --tags` -10. `eval $(gpg-agent --daemon)` -11. `gpg --use-agent --armor --detach-sign` and press ^C after authenticating - - if you run into issues with gpg [this](https://stackoverflow.com/questions/57591432/gpg-signing-failed-inappropriate-ioctl-for-device-on-macos-with-maven) might help -12. `mvn clean deploy` -13. Verify package release at [Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.docraptor%22%20AND%20a%3A%22docraptor%22) (takes anywhere from minutes to days) -14. Use the git tag and make a new release with `target/docraptor-*` attached, https://github.com/DocRaptor/docraptor-java/tags -15. Refresh documentation on docraptor.com +10. `script/release` +11. Verify package release at [Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.docraptor%22%20AND%20a%3A%22docraptor%22) (takes anywhere from minutes to days) +12. Open https://github.com/DocRaptor/docraptor-java/tags and make a new release for the version. Use the git tag as the name, CHANGELOG entries as the description, and attach `target/docraptor-*` to the release +13. Refresh documentation on docraptor.com ## Version Policy diff --git a/RELEASE_SETUP.md b/RELEASE_SETUP.md index 548d3a3..bc469fb 100644 --- a/RELEASE_SETUP.md +++ b/RELEASE_SETUP.md @@ -1,15 +1,23 @@ If you haven't released this package before, there are a few things you'll need to do ## Create a GPG key + +`script/release` should handle this for you, but if you run into trouble +read more. + `brew install gpg2` Use [this guide](http://central.sonatype.org/pages/working-with-pgp-signatures.html) for generating a key. ## Publish your public key to several key servers +`script/release` should handle this for you, but if you run into trouble +read more. Note you may get a verification email for keys.openpgp.org and you +may need to click the link in that email. + Get your key id `gpg2 --list-keys` (looks something like `453D1C92`) -- `gpg2 --keyserver hkp://pool.sks-keyservers.net --send-keys KEY_ID` +- `gpg --keyserver keys.openpgp.org --send-keys KEY_ID` - `gpg --keyserver keyserver.ubuntu.com --send-keys KEY_ID` - `gpg --keyserver pgp.mit.edu --send-keys KEY_ID` @@ -17,10 +25,14 @@ Then verify that your key is on one of those servers by looking on those servers - http://pgp.mit.edu/ - http://keyserver.ubuntu.com/ -- https://sks-keyservers.net/i/ +- https://keys.openpgp.org/ ## Sign up for Sonatype jira account at https://issues.sonatype.org -## Put those Sonatype credentials in ~/.m2/settings.xml + +`script/release` should handle this for you, but if you run into trouble +read more. + +Put those Sonatype credentials in ~/.m2/settings.xml it will look like ``` @@ -28,8 +40,8 @@ it will look like ossrh - divanov-oss.sonatype.org-account - divanov-oss.sonatype.org-password + YOUR_USERNAME + YOUR_PASSWORD diff --git a/api/openapi.yaml b/api/openapi.yaml index e2a7b54..ce8aff4 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -384,12 +384,14 @@ components: owner_password: owner_password no_default_style: true debug: true + page_margin: page_margin css_dpi: 5 profile: profile http_timeout: 6 no_compress: true disallow_annotate: true version: version + pdf_forms: true javascript: true no_author_style: true key_bits: 1 @@ -398,6 +400,8 @@ components: no_xinclude: true disallow_print: true disallow_copy: true + iframes: true + user_agent_token: user_agent_token name: name tag: tag strict: none @@ -480,6 +484,10 @@ components: type: string prince_options: $ref: '#/components/schemas/PrinceOptions' + user_agent_token: + description: A token that will be added to the user agent for all requests + made for document content while creating a PDF. + type: string required: - document_content - document_type @@ -503,12 +511,14 @@ components: owner_password: owner_password no_default_style: true debug: true + page_margin: page_margin css_dpi: 5 profile: profile http_timeout: 6 no_compress: true disallow_annotate: true version: version + pdf_forms: true javascript: true no_author_style: true key_bits: 1 @@ -517,6 +527,7 @@ components: no_xinclude: true disallow_print: true disallow_copy: true + iframes: true properties: baseurl: description: Set the baseurl for assets. @@ -619,6 +630,15 @@ components: pdf_title: description: "Specify the PDF title, part of the document's metadata." type: string + iframes: + description: Enable loading of iframes. + type: boolean + page_margin: + description: Specify the page margin distance. + type: string + pdf_forms: + description: Make form fields editable by default. + type: boolean type: object AsyncDoc: example: diff --git a/build.gradle b/build.gradle index 85b418b..9f90c24 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'idea' apply plugin: 'eclipse' group = 'com.docraptor' -version = '2.0.0' +version = '3.2.0' buildscript { repositories { diff --git a/docraptor.yaml b/docraptor.yaml index 6a8cc20..412a1cc 100644 --- a/docraptor.yaml +++ b/docraptor.yaml @@ -307,6 +307,9 @@ definitions: description: The date and time at which a hosted document will be removed and no longer available. Must be a properly formatted ISO 8601 datetime, like 1981-01-23T08:02:30-05:00. prince_options: $ref: '#/definitions/PrinceOptions' + user_agent_token: + type: string + description: A token that will be added to the user agent for all requests made for document content while creating a PDF. PrinceOptions: type: object @@ -428,6 +431,16 @@ definitions: pdf_title: type: string description: Specify the PDF title, part of the document's metadata. + iframes: + type: boolean + description: Enable loading of iframes. + nullable: true + page_margin: + type: string + description: Specify the page margin distance. + pdf_forms: + type: boolean + description: Make form fields editable by default. AsyncDoc: type: object diff --git a/generator-config.json b/generator-config.json index 6008146..eface31 100644 --- a/generator-config.json +++ b/generator-config.json @@ -4,7 +4,7 @@ "apiPackage": "com.docraptor", "groupId": "com.docraptor", "artifactId": "docraptor", - "artifactVersion": "2.0.0", + "artifactVersion": "3.2.0", "artifactUrl": "https://github.com/DocRaptor/docraptor-java", "artifactDescription": "A native client library for the DocRaptor HTML to PDF/XLS service.", "scmConnection": "scm:git:git@github.com:DocRaptor/docraptor-java.git", diff --git a/patches/01_add_maven_publishing_plugin.patch b/patches/01_add_maven_publishing_plugin.patch new file mode 100644 index 0000000..c6d418e --- /dev/null +++ b/patches/01_add_maven_publishing_plugin.patch @@ -0,0 +1,77 @@ +commit 7ccaab3c86c432b54fbbdbc79255bf68f9082930 +Author: Jason Gladish +Date: Wed Nov 16 18:32:31 2022 -0500 + + Fix release issue with nexus-staging-maven-plugin + + Why is this change needed? + -------------------------- + The generated pom.xml doesn't include this plugin, and it is necessary + to publish the finished package. Because it's a big XML file it's not + very obvious that it gets removed on generation. We want the rest of the + generated file so we get reasonable dependency version updates. + + How does it address the issue? + ------------------------------ + This commit adds the plugin back, which allows + `mvn clean deploy -P sign-artifacts` to work. This is slightly different + than the previous `mvn clean deploy` because the generated file moved + artifact signing into a different profile, in theory to keep most tasks + faster. `-P sign-artifacts` tell maven to apply the `sign-artifacts` + profile, which augments the deafult profile. + + This plugin is added to the default profile in case the gpg plugin is + moved to the default profile in the future (then we could remove the + `-P sign-artifacts` above). At the moment, though, it doesn't really + matter. + + The next commit will add an automatically applied patch after client + gneration that will reapply this change when necessary. This will help + by handling the situation automatically, or failing that complain that + the patch can't be applied which will indicate to the user that things + have changed and roughly what needs to happen next (fix and apply the + patch). + + The generated code seems to have some support to publishing to maven + using grandle, but it didn't seem to just work out of the box so this + commit preserves the previous behavior. In the future it might be worth + attempting to get closer to the golden path by switching to gradle. + + Any links to any relevant tickets, articles, or other resources? + --------------------------------------------------------------- + https://central.sonatype.org/publish/publish-guide/#initial-setup + https://central.sonatype.org/publish/publish-maven/#nexus-staging-maven-plugin-for-deployment-and-release + https://books.sonatype.com/mvnref-book/reference/profiles-sect-maven-profiles.html + https://stackoverflow.com/questions/31740785/why-order-of-maven-dependencies-matter + + Any screenshots? + ---------------- + + Did you complete all of the following? + -------------------------------------- + - Run test suite? + - Add new tests? + - Consider security implications and practices? + +diff --git a/pom.xml b/pom.xml +index 6c7bdb0..f918a1c 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -179,6 +179,17 @@ + + + ++ ++ org.sonatype.plugins ++ nexus-staging-maven-plugin ++ 1.6.8 ++ true ++ ++ ossrh ++ https://oss.sonatype.org/ ++ true ++ ++ + + + diff --git a/pom.xml b/pom.xml index 18b7b0a..1c943bf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ docraptor jar docraptor - 2.0.0 + 3.2.0 https://github.com/DocRaptor/docraptor-java A native client library for the DocRaptor HTML to PDF/XLS service. @@ -179,6 +179,17 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + true + + diff --git a/script/build b/script/build index 1844ca5..08340fd 100755 --- a/script/build +++ b/script/build @@ -7,7 +7,7 @@ if [[ `ls target/*.jar` ]] && [ "$1" == "lazy" ]; then exit fi -if uname | grep Darwin; then +if [[ "$INSIDE_DOCKER" != "true" ]]; then exec script/docker /app/script/build fi diff --git a/script/docker b/script/docker index 49d6fbe..2dfe0e5 100755 --- a/script/docker +++ b/script/docker @@ -1,5 +1,6 @@ #!/bin/bash set -e +[[ "$TRACE" == "true" ]] && set -x cd "$(dirname "$0")/.." OPTIND=1 @@ -20,7 +21,7 @@ done shift $((OPTIND-1)) if [[ "$image" == "" ]]; then - image="$(cat .runtime-environments | grep -v '^#' | tail -n 1)" + image="$(cat .runtime-environments | sed 's/[[:blank:]]*#.*//;/^[[:blank:]]*$/d' | tail -n 1)" echo "docker image (-i) unset, defaulting to: $image" fi @@ -33,14 +34,23 @@ fi command="$1" -cache_dir="$(pwd)/tmp/cache_${image}" -mkdir -p "$cache_dir" +mounts=() +while IFS=':' read -r source target; do + # Create the directory if it's not a special/magic path (like for ssh) + mkdir -p -m 700 "$source" &> /dev/null || true + + mounts+=(--volume) + mounts+=("${source}:${target}") + + # Can't pipe to the while loop because that causes a subshell, which means + # the variables set in the loop aren't available outside of it. +done < <(eval echo "\"$(grep -v '^#' .docker_mounts.list)\"") set -x docker run -it --rm \ --env-file .docker_env.list \ --env RUNTIME_ENV="${image}" \ --mount type=bind,source="$(pwd)",target=/app \ - --mount type=bind,source="${cache_dir}",target=/app/tmp/cache \ + "${mounts[@]}" \ "$image" \ "$command" diff --git a/script/generate_language b/script/generate_language index 9221df1..42b637d 100755 --- a/script/generate_language +++ b/script/generate_language @@ -1,5 +1,6 @@ #!/bin/bash set -e +[[ "$TRACE" == "true" ]] && set -x cd "$(dirname "$0")/.." LANGUAGE="$(cat .generator-language-identifier)" @@ -22,10 +23,18 @@ fi echo "Facilitating generated content review" tmp_dir=".review/tmp" review_root=".review/generated_files" +# Clear the tmp_dir, where we'll temporarily store our files so they aren't +# overwritten by the generated files. rm -rf "$tmp_dir" (cd "$review_root" && find . -type f) | while read file_path; do - mkdir -p "$(dirname "${tmp_dir}/$file_path")" - mv -v "$file_path" "${tmp_dir}/$file_path" + # Move our file out of the way so it doesn't get overwritten by the generated + # file, but only if the file exists. Some files, like the generated docs and + # tests, aren't useful to users to we generally remove them, but we still + # want to facilitate review of these generated files. + if [ -e "$file_path" ]; then + mkdir -p "$(dirname "${tmp_dir}/$file_path")" + mv -v "$file_path" "${tmp_dir}/$file_path" + fi done ./script/swagger generate \ @@ -41,6 +50,19 @@ fi # See .review/README.md echo "Facilitating generated content review" (cd "$review_root" && find . -type f) | while read file_path; do - mv -v "$file_path" "$review_root/$file_path" - mv -v "${tmp_dir}/$file_path" "$file_path" + # Update $review_root to match the generated files. + if [ -e "$file_path" ]; then + # Move the newly generated file into the review directory so we'll be able to + # see it in the diff. + mv -v "$file_path" "$review_root/$file_path" + else + # If the file doesn't exist, then it was removed by the generator, so we + # should remove it from the review directory as well. + rm -v "$review_root/$file_path" + fi + # If we temporarily stored a file (meaning it existed before the generation) + # then move it back into place. + if [ -e "${tmp_dir}/$file_path" ]; then + mv -v "${tmp_dir}/$file_path" "$file_path" + fi done diff --git a/script/inside_container/test b/script/inside_container/test index 840e4b6..89a762e 100755 --- a/script/inside_container/test +++ b/script/inside_container/test @@ -2,6 +2,9 @@ set -e cd "$(dirname "$0")/../.." +apt update +apt install poppler-utils -y + cd test # runs a test file with PASS/FAIL message diff --git a/script/post_generate_language b/script/post_generate_language index ab1acfe..37f8560 100755 --- a/script/post_generate_language +++ b/script/post_generate_language @@ -1,10 +1,8 @@ #!/bin/bash set -e +[[ "$TRACE" == "true" ]] && set -x cd "$(dirname "$0")/.." -echo "Removing autogenerated tests..." -rm -r src/test - echo "Removing trailing whitespace..." find src -name "*.java" -type f -exec sed -E -i '' 's/[[:space:]]+$//g' {} + find . -name "*.gradle" -depth 1 -type f -exec sed -E -i '' 's/[[:space:]]+$//g' {} + diff --git a/script/release b/script/release new file mode 100755 index 0000000..3ffe7b8 --- /dev/null +++ b/script/release @@ -0,0 +1,116 @@ +#!/bin/bash +set -e +[[ "$TRACE" == "true" ]] && set -x +cd "$(dirname "$0")/.." + +if [[ "$INSIDE_DOCKER" != "true" ]]; then + exec script/docker "/app/script/$(basename "$0")" +fi + +maven_settings_path="tmp/settings.xml" +if ! [ -f "$maven_settings_path" ]; then + echo "If you haven't already, you need to sign up for a Sonatype jira account" + echo "at https://issues.sonatype.org" + echo "Storing jira login information for maven publishing..." + read -p "Username: " username + read -s -p "Password: " password + echo + echo + cat >"$maven_settings_path" < + + + ossrh + ${username} + ${password} + + + +EOF +fi + +echo "Moving maven $maven_settings_path into place..." +mkdir -pv ~/.m2 +cp -vb "$maven_settings_path" ~/.m2/"$(basename "$maven_settings_path")" +echo "Moved." +echo + +echo "Setting up gnupg..." +mkdir -v ~/.gnupg +find ~/.gnupg_host_docraptor/ -maxdepth 1 -mindepth 1 -type d,f,l -exec cp -vr '{}' ~/.gnupg/ \; +chmod -R 700 ~/.gnupg/ + +echo "Installing gpg-agent..." +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get install -qq gpg-agent +echo "gpg-agent installed." +echo + +if [[ "$(gpg --list-keys)" == "" ]]; then + + echo "Collecting information for new gpg key used for maven publishing..." + read -p "Enter your first and last name: " name + read -p "Enter your email address: " email + + cat >tmp/keydetails < /dev/null` because we don't actually care about the +# signature output. This whole exercise is just to make sure the key is +# decrypted in the agent so mvn can sign files below. +export GPG_TTY=$(tty) +echo | gpg --use-agent --armor --detach-sign > /dev/null +echo "GPG key unlocked." +echo + +echo "Releasing..." +mvn clean deploy -P sign-artifacts +echo "Released." +echo diff --git a/script/test b/script/test index 7c482c7..e3a14ab 100755 --- a/script/test +++ b/script/test @@ -32,7 +32,7 @@ run_tests() { success="true" -for runtime_env in $(cat .runtime-environments | grep -v '^#'); do +for runtime_env in $(cat .runtime-environments | sed 's/[[:blank:]]*#.*//;/^[[:blank:]]*$/d'); do echo echo echo "Testing runtime env $runtime_env" diff --git a/src/main/java/com/docraptor/ApiClient.java b/src/main/java/com/docraptor/ApiClient.java index 3772fe3..4f099fe 100644 --- a/src/main/java/com/docraptor/ApiClient.java +++ b/src/main/java/com/docraptor/ApiClient.java @@ -98,7 +98,7 @@ public ApiClient() { dateFormat = ApiClient.buildDefaultDateFormat(); // Set default User-Agent. - setUserAgent("OpenAPI-Generator/2.0.0/java"); + setUserAgent("OpenAPI-Generator/3.2.0/java"); // Setup authentications (key: authentication name, value: authentication). authentications = new HashMap(); diff --git a/src/main/java/com/docraptor/Doc.java b/src/main/java/com/docraptor/Doc.java index 54aade9..b3a3480 100644 --- a/src/main/java/com/docraptor/Doc.java +++ b/src/main/java/com/docraptor/Doc.java @@ -46,7 +46,8 @@ Doc.JSON_PROPERTY_CALLBACK_URL, Doc.JSON_PROPERTY_HOSTED_DOWNLOAD_LIMIT, Doc.JSON_PROPERTY_HOSTED_EXPIRES_AT, - Doc.JSON_PROPERTY_PRINCE_OPTIONS + Doc.JSON_PROPERTY_PRINCE_OPTIONS, + Doc.JSON_PROPERTY_USER_AGENT_TOKEN }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class Doc { @@ -173,6 +174,9 @@ public static StrictEnum fromValue(String value) { public static final String JSON_PROPERTY_PRINCE_OPTIONS = "prince_options"; private PrinceOptions princeOptions; + public static final String JSON_PROPERTY_USER_AGENT_TOKEN = "user_agent_token"; + private String userAgentToken; + public Doc() { } @@ -635,6 +639,33 @@ public void setPrinceOptions(PrinceOptions princeOptions) { } + public Doc userAgentToken(String userAgentToken) { + + this.userAgentToken = userAgentToken; + return this; + } + + /** + * A token that will be added to the user agent for all requests made for document content while creating a PDF. + * @return userAgentToken + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "A token that will be added to the user agent for all requests made for document content while creating a PDF.") + @JsonProperty(JSON_PROPERTY_USER_AGENT_TOKEN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getUserAgentToken() { + return userAgentToken; + } + + + @JsonProperty(JSON_PROPERTY_USER_AGENT_TOKEN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setUserAgentToken(String userAgentToken) { + this.userAgentToken = userAgentToken; + } + + @Override public boolean equals(Object o) { if (this == o) { @@ -660,12 +691,13 @@ public boolean equals(Object o) { Objects.equals(this.callbackUrl, doc.callbackUrl) && Objects.equals(this.hostedDownloadLimit, doc.hostedDownloadLimit) && Objects.equals(this.hostedExpiresAt, doc.hostedExpiresAt) && - Objects.equals(this.princeOptions, doc.princeOptions); + Objects.equals(this.princeOptions, doc.princeOptions) && + Objects.equals(this.userAgentToken, doc.userAgentToken); } @Override public int hashCode() { - return Objects.hash(name, documentType, documentContent, documentUrl, test, pipeline, strict, ignoreResourceErrors, ignoreConsoleMessages, tag, help, javascript, referrer, callbackUrl, hostedDownloadLimit, hostedExpiresAt, princeOptions); + return Objects.hash(name, documentType, documentContent, documentUrl, test, pipeline, strict, ignoreResourceErrors, ignoreConsoleMessages, tag, help, javascript, referrer, callbackUrl, hostedDownloadLimit, hostedExpiresAt, princeOptions, userAgentToken); } @Override @@ -689,6 +721,7 @@ public String toString() { sb.append(" hostedDownloadLimit: ").append(toIndentedString(hostedDownloadLimit)).append("\n"); sb.append(" hostedExpiresAt: ").append(toIndentedString(hostedExpiresAt)).append("\n"); sb.append(" princeOptions: ").append(toIndentedString(princeOptions)).append("\n"); + sb.append(" userAgentToken: ").append(toIndentedString(userAgentToken)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/src/main/java/com/docraptor/PrinceOptions.java b/src/main/java/com/docraptor/PrinceOptions.java index 5f00264..0cc19f6 100644 --- a/src/main/java/com/docraptor/PrinceOptions.java +++ b/src/main/java/com/docraptor/PrinceOptions.java @@ -58,7 +58,10 @@ PrinceOptions.JSON_PROPERTY_JAVASCRIPT, PrinceOptions.JSON_PROPERTY_CSS_DPI, PrinceOptions.JSON_PROPERTY_PROFILE, - PrinceOptions.JSON_PROPERTY_PDF_TITLE + PrinceOptions.JSON_PROPERTY_PDF_TITLE, + PrinceOptions.JSON_PROPERTY_IFRAMES, + PrinceOptions.JSON_PROPERTY_PAGE_MARGIN, + PrinceOptions.JSON_PROPERTY_PDF_FORMS }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class PrinceOptions { @@ -189,6 +192,15 @@ public static InputEnum fromValue(String value) { public static final String JSON_PROPERTY_PDF_TITLE = "pdf_title"; private String pdfTitle; + public static final String JSON_PROPERTY_IFRAMES = "iframes"; + private Boolean iframes; + + public static final String JSON_PROPERTY_PAGE_MARGIN = "page_margin"; + private String pageMargin; + + public static final String JSON_PROPERTY_PDF_FORMS = "pdf_forms"; + private Boolean pdfForms; + public PrinceOptions() { } @@ -1002,6 +1014,87 @@ public void setPdfTitle(String pdfTitle) { } + public PrinceOptions iframes(Boolean iframes) { + + this.iframes = iframes; + return this; + } + + /** + * Enable loading of iframes. + * @return iframes + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Enable loading of iframes.") + @JsonProperty(JSON_PROPERTY_IFRAMES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getIframes() { + return iframes; + } + + + @JsonProperty(JSON_PROPERTY_IFRAMES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setIframes(Boolean iframes) { + this.iframes = iframes; + } + + + public PrinceOptions pageMargin(String pageMargin) { + + this.pageMargin = pageMargin; + return this; + } + + /** + * Specify the page margin distance. + * @return pageMargin + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Specify the page margin distance.") + @JsonProperty(JSON_PROPERTY_PAGE_MARGIN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getPageMargin() { + return pageMargin; + } + + + @JsonProperty(JSON_PROPERTY_PAGE_MARGIN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPageMargin(String pageMargin) { + this.pageMargin = pageMargin; + } + + + public PrinceOptions pdfForms(Boolean pdfForms) { + + this.pdfForms = pdfForms; + return this; + } + + /** + * Make form fields editable by default. + * @return pdfForms + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Make form fields editable by default.") + @JsonProperty(JSON_PROPERTY_PDF_FORMS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getPdfForms() { + return pdfForms; + } + + + @JsonProperty(JSON_PROPERTY_PDF_FORMS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPdfForms(Boolean pdfForms) { + this.pdfForms = pdfForms; + } + + @Override public boolean equals(Object o) { if (this == o) { @@ -1040,12 +1133,15 @@ public boolean equals(Object o) { Objects.equals(this.javascript, princeOptions.javascript) && Objects.equals(this.cssDpi, princeOptions.cssDpi) && Objects.equals(this.profile, princeOptions.profile) && - Objects.equals(this.pdfTitle, princeOptions.pdfTitle); + Objects.equals(this.pdfTitle, princeOptions.pdfTitle) && + Objects.equals(this.iframes, princeOptions.iframes) && + Objects.equals(this.pageMargin, princeOptions.pageMargin) && + Objects.equals(this.pdfForms, princeOptions.pdfForms); } @Override public int hashCode() { - return Objects.hash(baseurl, noXinclude, noNetwork, noParallelDownloads, httpUser, httpPassword, httpProxy, httpTimeout, insecure, media, noAuthorStyle, noDefaultStyle, noEmbedFonts, noSubsetFonts, noCompress, encrypt, keyBits, userPassword, ownerPassword, disallowPrint, disallowCopy, disallowAnnotate, disallowModify, debug, input, version, javascript, cssDpi, profile, pdfTitle); + return Objects.hash(baseurl, noXinclude, noNetwork, noParallelDownloads, httpUser, httpPassword, httpProxy, httpTimeout, insecure, media, noAuthorStyle, noDefaultStyle, noEmbedFonts, noSubsetFonts, noCompress, encrypt, keyBits, userPassword, ownerPassword, disallowPrint, disallowCopy, disallowAnnotate, disallowModify, debug, input, version, javascript, cssDpi, profile, pdfTitle, iframes, pageMargin, pdfForms); } @Override @@ -1082,6 +1178,9 @@ public String toString() { sb.append(" cssDpi: ").append(toIndentedString(cssDpi)).append("\n"); sb.append(" profile: ").append(toIndentedString(profile)).append("\n"); sb.append(" pdfTitle: ").append(toIndentedString(pdfTitle)).append("\n"); + sb.append(" iframes: ").append(toIndentedString(iframes)).append("\n"); + sb.append(" pageMargin: ").append(toIndentedString(pageMargin)).append("\n"); + sb.append(" pdfForms: ").append(toIndentedString(pdfForms)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/test/IframesDefault.java b/test/IframesDefault.java new file mode 100644 index 0000000..9f0205b --- /dev/null +++ b/test/IframesDefault.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class IframesDefault { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentContent( + "" + + "

Baseline text

" + + "" + + "" + ); + doc.setTest(true); + // PrinceOptions prince_options = new PrinceOptions(); + // prince_options.setIframes(true); + // doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(!output.contains("Test")) { + throw new IllegalArgumentException("output should have contained iframe content: " + output); + } + + } +} diff --git a/test/IframesFalse.java b/test/IframesFalse.java new file mode 100644 index 0000000..20575e9 --- /dev/null +++ b/test/IframesFalse.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class IframesFalse { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentContent( + "" + + "

Baseline text

" + + "" + + "" + ); + doc.setTest(true); + PrinceOptions prince_options = new PrinceOptions(); + prince_options.setIframes(false); + doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(output.contains("Test")) { + throw new IllegalArgumentException("output should not have contained iframe content: " + output); + } + + } +} diff --git a/test/IframesTrue.java b/test/IframesTrue.java new file mode 100644 index 0000000..71fcea5 --- /dev/null +++ b/test/IframesTrue.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class IframesTrue { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentContent( + "" + + "

Baseline text

" + + "" + + "" + ); + doc.setTest(true); + PrinceOptions prince_options = new PrinceOptions(); + prince_options.setIframes(true); + doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(!output.contains("Test")) { + throw new IllegalArgumentException("output should have contained iframe content: " + output); + } + + } +} diff --git a/test/PrinceOptionsTest.java b/test/PrinceOptionsTest.java new file mode 100644 index 0000000..03f8acd --- /dev/null +++ b/test/PrinceOptionsTest.java @@ -0,0 +1,59 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class PrinceOptionsTest { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + + // Verify the test works as expected by confirming that this url will fail + // without prince_options[insecure]=true. + Doc doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentUrl("https://expired.badssl.com/"); + doc.setTest(true); + + try { + docraptor.createDoc(doc); + } catch (com.docraptor.ApiException ex) { + String expected_message = "SSL Error downloading document content from supplied url."; + if (!ex.getMessage().contains(expected_message)) { + System.out.println("Wrong exception, expected: " + expected_message + ", got: " + ex.getMessage()); + System.exit(1); + } + } + + + // Verify prince_options works by testing a url that will fail without + // prince_options[insecure]=true. + doc = new Doc(); + doc.setName("java-sync.pdf"); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentUrl("https://expired.badssl.com/"); + doc.setTest(true); + PrinceOptions prince_options = new PrinceOptions(); + prince_options.setInsecure(true); + doc.setPrinceOptions(prince_options); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + } +} diff --git a/test/UserAgentTokenTest.java b/test/UserAgentTokenTest.java new file mode 100644 index 0000000..acee39d --- /dev/null +++ b/test/UserAgentTokenTest.java @@ -0,0 +1,53 @@ +import java.io.*; +import java.net.*; +import com.docraptor.*; + +public class UserAgentTokenTest { + public static void main(String[] args) throws Exception { + DocApi docraptor = new DocApi(); + ApiClient client = docraptor.getApiClient(); + client.setUsername("YOUR_API_KEY_HERE"); + // client.setDebugging(true); + + // Verify prince_options works by testing a url that will fail without + // prince_options[insecure]=true. + Doc doc = new Doc(); + doc.setName("java-ua-token.pdf"); + doc.setTest(true); + doc.setDocumentType(Doc.DocumentTypeEnum.PDF); + doc.setDocumentUrl("https://docraptor-test-harness.herokuapp.com/agent/agent_tester.html"); + doc.setUserAgentToken("SpecialToken Yay!"); + + byte data[] = docraptor.createDoc(doc); + + String output_file = System.getenv("TEST_OUTPUT_DIR") + + "/" + System.getenv("TEST_NAME") + "_csharp_" + + System.getenv("RUNTIME_ENV") + ".pdf"; + + FileOutputStream out = new FileOutputStream(output_file); + out.write(data); + out.close(); + + BufferedReader br = new BufferedReader(new FileReader(output_file)); + String line = br.readLine(); + if (!line.contains("%PDF-1.5")) { + throw new IllegalArgumentException("unexpected file header: " + line); + } + + String command = "pdftotext " + output_file + " -"; + + String[] commands = {"bash", "-c", command}; + Process p = Runtime.getRuntime().exec(commands); + p.waitFor(); + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String output = ""; + while ((line = b.readLine()) != null) { + output += line; + } + b.close(); + + if(!output.contains("SpecialToken Yay!")) { + throw new IllegalArgumentException("output should have contained user agent token content: " + output); + } + } +}