1 {-# LANGUAGE OverloadedStrings #-}
3 import Control.Concurrent (threadDelay)
4 import qualified Control.Exception as X
5 import Control.Monad (forever)
6 import qualified Data.ByteString.Lazy.Char8 as BL
7 import qualified Data.Text as T
8 import Data.Version (showVersion)
9 import Data.Word (Word64)
11 import Network.AMQP.Utils.Connection
12 import Network.AMQP.Utils.Helpers
13 import Network.AMQP.Utils.Options
14 import Paths_amqp_utils (version)
15 import System.Environment
17 import qualified System.Posix.Files as F
19 import Data.Time.Clock.POSIX
24 args <- getArgs >>= parseargs "agitprop"
25 printparam' "client version" $ "amqp-utils " ++ (showVersion version)
26 printparam' "routing key" $ rKey args
27 isDir <- F.getFileStatus (inputFile args) >>= return . F.isDirectory
29 then printparam' "hotfolder" $ inputFile args
30 else printparam' "input file" $
33 then " (line-by-line)"
35 (conn, chan) <- connect args
36 printparam' "confirm mode" $ show $ confirm args
39 confirmSelect chan False
40 addConfirmationListener chan confirmCallback
42 let publishOneMsg = publishOneMsg' chan args
46 inotify <- initINotify
52 (handleEvent publishOneMsg)
53 hr $ "watching " ++ (inputFile args)
54 _ <- forever $ threadDelay 1000000
57 hr $ "sending " ++ (inputFile args)
58 messageFile <- BL.readFile (inputFile args)
60 then mapM_ publishOneMsg (BL.lines messageFile)
61 else publishOneMsg messageFile)
62 (\exception -> printparam' "exception" $ show (exception :: X.SomeException))
63 -- all done. wait and close.
65 then waitForConfirms chan >>= return . show >> return ()
69 -- | The handler for publisher confirms
70 confirmCallback :: (Word64, Bool, AckType) -> IO ()
71 confirmCallback (deliveryTag, isAll, ackType) =
74 ((show deliveryTag) ++
80 -- | Hotfolder event handler
81 handleEvent :: (BL.ByteString -> IO ()) -> Event -> IO ()
82 -- just handle closewrite and movedin events
83 handleEvent f (Closed False (Just x) True) = handleFile f x
84 handleEvent f (MovedIn False x _) = handleFile f x
85 handleEvent _ _ = return ()
87 -- | Hotfolder file handler
88 handleFile :: (BL.ByteString -> IO ()) -> FilePath -> IO ()
89 handleFile _ ('.':_) = return () -- ignore hidden files
92 (hr ("sending " ++ x) >> BL.readFile x >>= f)
94 printparam' "exception in handleFile" $
95 show (exception :: X.SomeException))
97 -- | Publish one message with our settings
98 publishOneMsg' :: Channel -> Args -> BL.ByteString -> IO ()
99 publishOneMsg' c a f = do
100 now <- getCurrentTime >>= return.floor.utcTimeToPOSIXSeconds
104 (T.pack $ currentExchange a)
107 , msgDeliveryMode = Just Persistent
108 , msgTimestamp = Just now
110 , msgType = msgtype a
111 , msgUserID = msguserid a
112 , msgApplicationID = msgappid a
113 , msgClusterID = msgclusterid a
114 , msgContentType = msgcontenttype a
115 , msgContentEncoding = msgcontentencoding a
116 , msgReplyTo = msgreplyto a
117 , msgPriority = msgprio a
118 , msgCorrelationID = msgcorrid a
119 , msgExpiration = msgexp a
120 , msgHeaders = msgheader a
122 printparam "sent" $ fmap show r