1 import Control.Applicative( (<$>) )
2 import Control.Monad( unless )
3 import Data.Time.Clock( UTCTime(..) )
4 import Diddo( DiddoEntry(..), LogEntry(..), parseDiddoLogline, formatDiddoEntry, timestamp, logToDiddoEntry )
5 import System.Console.GetOpt
6 import System.Environment( getArgs )
7 import System.Exit( exitSuccess, exitFailure )
8 import System.IO( stderr, hPutStr )
9 import qualified Data.Map as Map
10 import qualified Data.Text as T
11 import qualified Data.Text.IO as TIO
17 , optInputFiles :: [String]
18 , optOutputFile :: String
19 , optInputFormat :: String
20 , optOutputFormat :: String
21 , optStartDate :: String
22 , optEndDate :: String
32 , optInputFormat = "%FT%T%z"
33 , optOutputFormat = "%FT%T%z"
38 availableOptions :: [OptDescr (Opt -> IO Opt)]
40 [ Option ['h'] ["help"]
41 (NoArg (\_ -> putStrLn (usageInfo "Usage: diddohs [OPTION...]" availableOptions) >> exitSuccess))
42 "Display program help"
43 , Option ['v'] ["verbose"]
44 (NoArg (\opts -> return opts { optVerbose = True }))
45 "More detailed output"
46 , Option ['V'] ["version"]
47 (NoArg (\opts -> return opts { optVersion = True }))
48 "Display program version"
49 , Option ['f'] ["file"]
50 (ReqArg (\arg opts -> return opts { optInputFiles = optInputFiles opts ++ [arg]}) "FILE" )
52 , Option ['w'] ["output"]
53 (ReqArg (\arg opts -> return opts { optOutputFile = arg }) "FILE")
55 , Option ['i'] ["informat"]
56 (ReqArg (\arg opts -> return opts { optInputFormat = arg }) "FORMAT")
57 "Timeformat used in input"
58 , Option ['o'] ["outformat"]
59 (ReqArg (\arg opts -> return opts { optOutputFormat = arg }) "FORMAT")
60 "Timeformat used in output"
61 , Option ['s'] ["start"]
62 (ReqArg (\arg opts -> return opts { optStartDate = arg }) "DATE")
63 "Start of reporting period"
64 , Option ['e'] ["end"]
65 (ReqArg (\arg opts -> return opts { optEndDate = arg }) "DATE")
66 "End of reporting period"
69 -- SECTION: Map of logentries to Map of DiddoEntries
70 mapToDiddoEntries :: Map.Map UTCTime Diddo.LogEntry -> Map.Map UTCTime Diddo.DiddoEntry
71 mapToDiddoEntries logmap = Map.mapWithKey toDddEntry logmap
73 toDddEntry key value = Diddo.logToDiddoEntry (preceedingTimestamp key) value
74 preceedingTimestamp x = case Map.lookupLT x logmap of
76 Nothing -> fst $ Map.findMin logmap
77 -- SECTION: Map of logentries to Map of DiddoEntries
81 -- SECTION: option processing
82 (givenOptions,args,errs) <- getArgs >>= return . getOpt Permute availableOptions
84 unless (null errs) $ do
85 mapM_ (hPutStr stderr) errs
88 effectiveOptions <- foldl (>>=) (return defaultOpts) givenOptions
89 -- SECTION: option processing
92 map Diddo.parseDiddoLogline <$> case optInputFiles effectiveOptions of
93 files@(_:_) -> T.lines . T.concat <$> mapM TIO.readFile files
94 [] -> T.lines <$> TIO.getContents
97 dddLogEntryMap = Map.fromList $ map (\diddo -> (Diddo.timestamp diddo, diddo)) dddLogEntries
98 diddoEntriesMap = mapToDiddoEntries dddLogEntryMap
99 inDateFmt = optInputFormat effectiveOptions
100 outDateFmt = optOutputFormat effectiveOptions
106 mapM_ (TIO.putStrLn . snd) $ Map.toAscList $ Map.map (Diddo.formatDiddoEntry outDateFmt) diddoEntriesMap