module Yesod.Content.PDF where
import Prelude
import Yesod.Core.Content
import Data.ByteString
import Text.Blaze.Html
import Text.Blaze.Html.Renderer.String
import Blaze.ByteString.Builder.ByteString
import System.Process
import System.IO.Temp
import System.IO
import Network.URI
import Data.Conduit
newtype PDF = PDF ByteString
typePDF :: ContentType
typePDF = "application/pdf"
instance HasContentType PDF where
getContentType _ = typePDF
instance ToTypedContent PDF where
toTypedContent = TypedContent typePDF . toContent
instance ToContent PDF where
toContent (PDF bs) = ContentSource $ do
yield $ Chunk $ fromByteString bs
uri2PDF :: URI -> IO PDF
uri2PDF uri = withSystemTempFile "output.pdf" $ uri2PDF' uri
where
uri2PDF' :: URI -> FilePath -> Handle -> IO PDF
uri2PDF' uri' tempPDFFile tempHandle = do
hClose tempHandle
(_,_,_, pHandle) <- createProcess (proc "wkhtmltopdf" ["--quiet", show uri', tempPDFFile])
_ <- waitForProcess pHandle
PDF <$> Data.ByteString.readFile tempPDFFile
html2PDF :: Html -> IO PDF
html2PDF html = withSystemTempFile "output.pdf" (html2PDF' html)
where
html2PDF' :: Html -> FilePath -> Handle -> IO PDF
html2PDF' html' tempPDFFile tempPDFHandle = do
hClose tempPDFHandle
withSystemTempFile "input.html" $ \tempHtmlFile tempHtmlHandle -> do
System.IO.hPutStrLn tempHtmlHandle $ renderHtml html'
hClose tempHtmlHandle
(_,_,_, pHandle) <- createProcess (proc "wkhtmltopdf" ["--quiet", tempHtmlFile, tempPDFFile])
_ <- waitForProcess pHandle
PDF <$> Data.ByteString.readFile tempPDFFile