summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2018-03-15 07:46:38 -0400
committerAndrew Cady <d@jerkface.net>2018-03-15 07:48:26 -0400
commit511913f92b667e8d7ca2252ec23433bcda6c43ec (patch)
tree83eab1474ea9262c614b47b3c8fe82d4dcfc391e
parente4ad9a4b5512ed3a7779ae848f2c95df24ee46b8 (diff)
Two fixes
1. Avoid a race condition (PDF gets copied before CUPS fully writes it). 2. Work aaround PDFToPrinter.exe limitation (cannot render some text) by running PDFs through ImageMagick to rasterize them.
-rw-r--r--Main.hs43
-rw-r--r--package.yaml2
2 files changed, 42 insertions, 3 deletions
diff --git a/Main.hs b/Main.hs
index 2e00d1e..0fba75a 100644
--- a/Main.hs
+++ b/Main.hs
@@ -1,4 +1,5 @@
1{-# LANGUAGE NoImplicitPrelude #-} 1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE NoImplicitPrelude #-}
2module Main where 3module Main where
3import Rebase.Prelude 4import Rebase.Prelude
4 5
@@ -7,6 +8,11 @@ import Options.Applicative (execParser, help, helper, info, long,
7import System.Directory (createDirectoryIfMissing, renameFile) 8import System.Directory (createDirectoryIfMissing, renameFile)
8import System.FilePath (takeFileName, (</>)) 9import System.FilePath (takeFileName, (</>))
9import System.FSNotify (Event (..), watchDir, withManager) 10import System.FSNotify (Event (..), watchDir, withManager)
11import System.IO.Temp (withSystemTempDirectory)
12import System.Posix.Files (fileMode, getFileStatus,
13 intersectFileModes, nullFileMode,
14 otherReadMode)
15import System.Posix.Types (FileMode)
10import System.Process.Typed (proc, runProcess) 16import System.Process.Typed (proc, runProcess)
11 17
12pdfDirectory, seenDir, pdfPrinterExecutable :: FilePath 18pdfDirectory, seenDir, pdfPrinterExecutable :: FilePath
@@ -47,9 +53,40 @@ pdfPrinter f =
47 runProcessVerbose pdfPrinterExecutable [f] >> 53 runProcessVerbose pdfPrinterExecutable [f] >>
48 moveFileIntoDir f seenDir 54 moveFileIntoDir f seenDir
49 55
56hasMode :: FileMode -> FileMode -> Bool
57hasMode = ((.).(.)) (/= nullFileMode) intersectFileModes
58
59newtype Milliseconds = Milliseconds Integer deriving (Num, Show, Eq, Ord)
60waitUntil :: (IO Bool) -> Milliseconds -> IO ()
61waitUntil cond maxWait = do
62 r <- cond
63 when (maxWait > 0 && not r) $ do
64 threadDelay $ 100 * 1000
65 waitUntil cond (maxWait - 100)
66
67waitUntilReadable :: FilePath -> Milliseconds -> IO ()
68waitUntilReadable f = waitUntil $ hasMode otherReadMode . fileMode <$> getFileStatus f
69
50pdfSender :: String -> FilePath -> IO () 70pdfSender :: String -> FilePath -> IO ()
51pdfSender target f = 71pdfSender target f = do
52 runProcessVerbose "rsync" ["--remove-source-files", f, target] >> return () 72 withSystemTempDirectory "pdf-autoprint." $ \dir -> do
73 -- CUPS creates the file (with its final name) and then appends to it,
74 -- rather than atomically renaming a fully-written file into place. Luckily
75 -- we can still detect when the file is fully-written because CUPS will
76 -- change the permissions from 600 to 644 after it is. Thus we poll until
77 -- the permissions change. This isn't really the best approach; we could use
78 -- fs notifications here too. We currently do get a 'Modified' event on the
79 -- file, with which we do nothing. However, I am not sure that this event is
80 -- not triggered too early.
81 waitUntilReadable f (100*1000)
82
83 -- `PDFToPrinter.exe` will render text on (at least) the IRS tax forms as
84 -- horrible pixelated smudgy blobs. This `convert` command will render the
85 -- text into a rasterized PDF that `PDFToPrinter.exe` can handle well.
86 let converted = dir </> takeFileName f
87 void $ runProcessVerbose "convert" ["-density", "300", f, converted]
88
89 void $ runProcessVerbose "rsync" ["--remove-source-files", converted, target]
53 90
54handlePdfsForever :: FilePath -> (FilePath -> IO ()) -> IO () 91handlePdfsForever :: FilePath -> (FilePath -> IO ()) -> IO ()
55handlePdfsForever dir h = handleEventsForever dir (handleAdds (".pdf" `isSuffixOf`) h) 92handlePdfsForever dir h = handleEventsForever dir (handleAdds (".pdf" `isSuffixOf`) h)
diff --git a/package.yaml b/package.yaml
index 3dfc2f3..1af60b7 100644
--- a/package.yaml
+++ b/package.yaml
@@ -13,6 +13,8 @@ dependencies:
13- typed-process 13- typed-process
14- filepath 14- filepath
15- optparse-applicative 15- optparse-applicative
16- temporary
17- unix
16 18
17executables: 19executables:
18 pdf-autoprint: 20 pdf-autoprint: