Skip to content

Commit

Permalink
refactor: move ResponseData out of the core package, rename structs…
Browse files Browse the repository at this point in the history
… and add better documentation
  • Loading branch information
le0m committed Aug 6, 2024
1 parent e183bed commit 3d665cb
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 18 deletions.
18 changes: 13 additions & 5 deletions print2pdf/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import (
"github.com/chromedp/chromedp"
)

// Represents a print format's width and height, in inches.
type PrintFormat struct {
Width float64
Height float64
}

// Taken from https://pptr.dev/api/puppeteer.paperformat.
// Map of format names to their dimensions, in inches. Taken from https://pptr.dev/api/puppeteer.paperformat.
var FormatsMap = map[string]PrintFormat{
"Letter": {8.5, 11},
"Legal": {8.5, 14},
Expand All @@ -34,19 +35,25 @@ var FormatsMap = map[string]PrintFormat{
"A6": {4.13, 5.83},
}

// Validation error in supplied parameter.
type ValidationError struct {
message string
}

// Implement error interface.
func (v ValidationError) Error() string {
return v.message
}

// Create a new validation error.
func NewValidationError(message string) ValidationError {
return ValidationError{message}
}

// Chromium binary path. Required.
var ChromiumPath = os.Getenv("CHROMIUM_PATH")

// Reference to browser context, initialized in `init()` function of this package.
var browserCtx context.Context

// Allocate a browser to be reused by multiple handler invocations, to reduce startup time.
Expand Down Expand Up @@ -78,7 +85,7 @@ func init() {
}()
}

// Get print format sizes from string name.
// Get print format dimensions from string name.
func getFormat(format string) (PrintFormat, error) {
f, ok := FormatsMap[format]
if !ok {
Expand All @@ -93,8 +100,9 @@ func getFormat(format string) (PrintFormat, error) {
return f, nil
}

// Prepare print parameters from request data, with defaults.
func getPrintParams(data RequestData) (page.PrintToPDFParams, error) {
// Prepare chromedp's print parameters from provider parameters, with defaults.
// Return an error if validation of any parameter fails.
func getPrintParams(data GetPDFParams) (page.PrintToPDFParams, error) {
params := page.PrintToPDFParams{
PrintBackground: true,
Landscape: false,
Expand Down Expand Up @@ -148,7 +156,7 @@ func getPrintParams(data RequestData) (page.PrintToPDFParams, error) {
}

// Get a buffer of bytes representing a webpage in PDF format.
func GetPDFBuffer(ctx context.Context, data RequestData, res *[]byte) error {
func GetPDFBuffer(ctx context.Context, data GetPDFParams, res *[]byte) error {
defer Elapsed("Total time to print PDF")()

params, err := getPrintParams(data)
Expand Down
40 changes: 28 additions & 12 deletions print2pdf/print2pdf.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
/*
Package print2pdf provides functions to save a webpage as a PDF file, leveraging Chromium and the DevTools Protocol.
Requires two environment variables to be set:
- `CHROMIUM_PATH` with the full path to the Chromium binary
- `BUCKET` with the name of the AWS S3 bucket
This packages uses `init()` functions to initialize the AWS SDK and start an headless instance of Chromium, to reduce
startup time when used as a web service.
*/
package print2pdf

// Page margins of the generated PDF, in inches.
type PrintMargins struct {
Top float64 `json:"top,omitempty"`
Bottom float64 `json:"bottom,omitempty"`
Left float64 `json:"left,omitempty"`
Right float64 `json:"right,omitempty"`
}

type RequestData struct {
Url string `json:"url"`
FileName string `json:"file_name"`
Media string `json:"media,omitempty"`
Format string `json:"format,omitempty"`
Background *bool `json:"background,omitempty"` // pointer to handle missing value from request (nil, false, true)
Layout string `json:"layout,omitempty"`
Margins *PrintMargins `json:"margin,omitempty"` // pointer to handle missing value from request (nil, PrintMargins)
Scale float64 `json:"scale,omitempty"`
}

type ResponseData struct {
// Parameters for generating a PDF.
type GetPDFParams struct {
// URL of the webpage to save. Required.
Url string `json:"url"`
// Filename of the generated PDF. A `.pdf` suffix will be appended if not present. Required.
FileName string `json:"file_name"`
// Media type to emulate. Accepted values are `"print"` and `"screen"`. Default is `"print"`.
Media string `json:"media,omitempty"`
// Page format. See [FormatsMap] for accepted values. Default is `"A4"`.
Format string `json:"format,omitempty"`
// Print background graphics. Default is `true`.
Background *bool `json:"background,omitempty"`
// Page orientation. Accepted values are `"landscape"` and `"portrait"`. Default is `"portrait"`.
Layout string `json:"layout,omitempty"`
// Page margins in inches. Default is all `0`.
Margins *PrintMargins `json:"margin,omitempty"`
// Scale of the webpage rendering. Default is `1`
Scale float64 `json:"scale,omitempty"`
}
4 changes: 3 additions & 1 deletion print2pdf/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (

// S3 bucket name. Required.
var BucketName = os.Getenv("BUCKET")

// Reference to AWS S3 client, initialized in `init()` function of this package.
var s3Client *s3.Client

// Initialize AWS SDK.
Expand All @@ -32,7 +34,7 @@ func init() {
s3Client = s3.NewFromConfig(cfg)
}

// Upload a file to S3 with a randomly prefixed key.
// Upload a file to S3. A random UUIDv4 prefix is added to the filename and used as key in the bucket, to avoid collisions.
func UploadFile(ctx context.Context, fileName string, contents *[]byte) (string, error) {
uuidv4, err := uuid.NewRandom()
if err != nil {
Expand Down

0 comments on commit 3d665cb

Please sign in to comment.