Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Vapor 2 #2

Merged
merged 2 commits into from
May 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 31 additions & 43 deletions Package.pins
Original file line number Diff line number Diff line change
Expand Up @@ -2,112 +2,100 @@
"autoPin": true,
"pins": [
{
"package": "CLibreSSL",
"package": "BCrypt",
"reason": null,
"repositoryURL": "https://github.com/vapor/clibressl.git",
"repositoryURL": "https://github.com/vapor/bcrypt.git",
"version": "1.0.0"
},
{
"package": "Bits",
"reason": null,
"repositoryURL": "https://github.com/vapor/bits.git",
"version": "1.0.0"
},
{
"package": "Console",
"reason": null,
"repositoryURL": "https://github.com/vapor/console.git",
"version": "1.0.2"
"version": "2.0.0"
},
{
"package": "Core",
"reason": null,
"repositoryURL": "https://github.com/vapor/core.git",
"version": "1.1.1"
"version": "2.0.0"
},
{
"package": "Crypto",
"reason": null,
"repositoryURL": "https://github.com/vapor/crypto.git",
"version": "1.1.0"
"version": "2.0.0"
},
{
"package": "Engine",
"package": "CTLS",
"reason": null,
"repositoryURL": "https://github.com/vapor/engine.git",
"version": "1.3.12"
"repositoryURL": "https://github.com/vapor/ctls.git",
"version": "1.0.0"
},
{
"package": "Fluent",
"package": "Debugging",
"reason": null,
"repositoryURL": "https://github.com/vapor/fluent.git",
"version": "1.4.3"
"repositoryURL": "https://github.com/vapor/debugging.git",
"version": "1.0.0"
},
{
"package": "Jay",
"package": "Engine",
"reason": null,
"repositoryURL": "https://github.com/DanToml/Jay.git",
"version": "1.0.1"
"repositoryURL": "https://github.com/vapor/engine.git",
"version": "2.0.0"
},
{
"package": "JSON",
"reason": null,
"repositoryURL": "https://github.com/vapor/json.git",
"version": "1.0.6"
},
{
"package": "Leaf",
"reason": null,
"repositoryURL": "https://github.com/vapor/leaf.git",
"version": "1.0.7"
"version": "2.0.0"
},
{
"package": "Multipart",
"reason": null,
"repositoryURL": "https://github.com/vapor/multipart.git",
"version": "1.0.3"
"version": "2.0.0"
},
{
"package": "Node",
"reason": null,
"repositoryURL": "https://github.com/vapor/node.git",
"version": "1.0.1"
"version": "2.0.0"
},
{
"package": "PathIndexable",
"package": "Random",
"reason": null,
"repositoryURL": "https://github.com/vapor/path-indexable.git",
"repositoryURL": "https://github.com/vapor/random.git",
"version": "1.0.0"
},
{
"package": "Polymorphic",
"reason": null,
"repositoryURL": "https://github.com/vapor/polymorphic.git",
"version": "1.0.1"
},
{
"package": "Routing",
"reason": null,
"repositoryURL": "https://github.com/vapor/routing.git",
"version": "1.1.0"
"version": "2.0.0"
},
{
"package": "Socks",
"package": "Sockets",
"reason": null,
"repositoryURL": "https://github.com/vapor/socks.git",
"version": "1.2.7"
"repositoryURL": "https://github.com/vapor/sockets.git",
"version": "2.0.0"
},
{
"package": "TLS",
"reason": null,
"repositoryURL": "https://github.com/vapor/tls.git",
"version": "1.1.2"
},
{
"package": "Turnstile",
"reason": null,
"repositoryURL": "https://github.com/stormpath/Turnstile.git",
"version": "1.0.6"
"version": "2.0.0"
},
{
"package": "Vapor",
"reason": null,
"repositoryURL": "https://github.com/vapor/vapor.git",
"version": "1.5.14"
"version": "2.0.0"
}
],
"version": 1
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import PackageDescription
let package = Package(
name: "wkhtmltopdf",
dependencies: [
.Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1, minor: 5),
.Package(url: "https://github.com/vapor/vapor.git", majorVersion: 2),
]
)
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
# wkhtmltopdf

![Swift](http://img.shields.io/badge/swift-3.1-brightgreen.svg)
![Vapor](http://img.shields.io/badge/vapor-1.5-brightgreen.svg)
![Vapor](http://img.shields.io/badge/vapor-2.0-brightgreen.svg)
![Travis](https://travis-ci.org/vapor-community/wkhtmltopdf.svg?branch=master)

---

**Vapor 2**: this package is *not* compatible with Vapor 2 beta. Once Vapor 2
moves out of beta, this package will be updated.

---

Vapor library for converting HTML (Leaf or otherwise) into PDF files using
Vapor 2 library for converting HTML (Leaf or otherwise) into PDF files using
[wkhtmltopdf](http://wkhtmltopdf.org/).

## 📘 Overview
Expand Down Expand Up @@ -44,7 +37,7 @@ document.pages = [page1, page2, page3]
// Render to a PDF
let pdf = try document.generatePDF()
// Now you can return the PDF as a response, if you want
let response = Response(status: .ok, body: .data(try pdf.makeBytes()))
let response = Response(status: .ok, body: .data(pdf))
response.headers["Content-Type"] = "application/pdf"
return response
```
Expand Down Expand Up @@ -74,6 +67,13 @@ Here is a worked example Leaf file which loads CSS and images. It uses the
</html>
```

### Zoom calibration

Across different platforms, `wkhtmltopdf` can require different zoom levels to
ensure that 1 mm in HTML equals 1 mm in PDF. The default zoom level is `1.3`,
which has been found to work well on Linux, but if you need a different zoom
level set the static property `Document.zoom` before doing any rendering.

### Why Pages?

WebKit is not very good at rendering page breaks. If it works with your design,
Expand Down
18 changes: 11 additions & 7 deletions Sources/wkhtmltopdf/Document+Generate.swift
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
import Foundation
import Core

#if os(Linux) && !swift(>=3.1)
typealias Process = Task
#endif

extension Document {

public func generatePDF() throws -> Data {
public func generatePDF() throws -> Bytes {
// Create the temp folder if it doesn't already exist
let workDir = "/tmp/vapor-wkhtmltopdf"
try FileManager().createDirectory(atPath: workDir, withIntermediateDirectories: true)
// Save input pages to temp files, and build up args to wkhtmltopdf
var wkArgs: [String] = [
"--zoom", "1.3", // NOTE: this may need changing in different deployments
"--zoom", Document.zoom,
"--quiet",
"-s", paperSize,
"-T", "\(topMargin)mm",
"-R", "\(rightMargin)mm",
"-B", "\(bottomMargin)mm",
"-L", "\(leftMargin)mm",
]
let fm = DataFile(workDir: workDir)
let pageFiles: [String] = try pages.map { page in
let fileName = "/tmp/vapor-wkhtmltopdf." + UUID().uuidString + ".html"
try page.content.write(toFile: fileName, atomically: false, encoding: .utf8)
let fileName = "\(workDir)/\(UUID().uuidString).html"
try fm.write(page.content, to: fileName)
return fileName
}
defer {
let fm = FileManager()
pageFiles.forEach { path in
try? fm.removeItem(atPath: path)
try? fm.delete(at: path)
}
}
wkArgs += pageFiles
Expand All @@ -38,7 +42,7 @@ extension Document {
wk.standardOutput = stdout
wk.launch()
let pdf = stdout.fileHandleForReading.readDataToEndOfFile()
return pdf
return pdf.makeBytes()
}

}
3 changes: 3 additions & 0 deletions Sources/wkhtmltopdf/Document.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
public class Document {

// This may need changing across different platforms and deployments.
static var zoom: String = "1.3"

let topMargin: Int
let rightMargin: Int
let bottomMargin: Int
Expand Down
6 changes: 3 additions & 3 deletions Sources/wkhtmltopdf/Page+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ extension Page {

public init(_ drop: Droplet, view path: String, _ context: Node? = nil) throws {
var ctx = context ?? Node.object([:])
ctx["workDir"] = drop.workDir.makeNode()
ctx["publicDir"] = (drop.workDir + "Public/").makeNode()
ctx["workDir"] = drop.config.workDir.makeNode(in: nil)
ctx["publicDir"] = (drop.config.workDir + "Public/").makeNode(in: nil)
let view = try drop.view.make(path, ctx)
self.init(view.data.string)
self.init(view.data)
}

}
10 changes: 8 additions & 2 deletions Sources/wkhtmltopdf/Page.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import Bits

public struct Page {

let content: String
let content: Bytes

public init(_ content: String) {
public init(_ content: Bytes) {
self.content = content
}

public init(_ content: String) {
self.content = content.makeBytes()
}

}
9 changes: 8 additions & 1 deletion Tests/wkhtmltopdfTests/wkhtmltopdfTests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import XCTest
@testable import wkhtmltopdf
import Core

class wkhtmltopdfTests: XCTestCase {
static var allTests = [
Expand All @@ -10,6 +11,12 @@ class wkhtmltopdfTests: XCTestCase {
let document = Document(margins: 15)
let page1 = Page("<p>Page from direct HTML</p>")
document.pages = [page1]
_ = try document.generatePDF()
let data = try document.generatePDF()
// Cop-out test, just ensuring that the returned data is something
XCTAssert(data.count > 50)
// Visual test
let fm = DataFile(workDir: "/tmp/vapor-wkhtmltopdf")
try fm.write(data, to: "/tmp/vapor-wkhtmltopdf/testOutput.pdf")
print("Test output PDF can be viewed at /tmp/vapor-wkhtmltopdf/testOutput.pdf")
}
}