]> git.netwichtig.de Git - user/henk/code/haskell/diddohs.git/blob - src/Main.hs
Changed format and structure a bit
[user/henk/code/haskell/diddohs.git] / src / Main.hs
1 import Control.Applicative( (<$>) )
2 import Control.Monad( unless )
3 import Data.Time.Clock( UTCTime(..) )
4 import Data.Time.LocalTime( TimeZone(), ZonedTime(..), zonedTimeToUTC, utcToZonedTime )
5 import Diddo( Diddo(..), LogEntry(..), parseDiddoLogline, formatDiddo, logToDiddo, parseToZonedTime )
6 import System.Console.GetOpt
7 import System.Environment( getArgs )
8 import System.Exit( exitSuccess, exitFailure )
9 import System.IO( stderr, hPutStr )
10 import qualified Data.Map as Map
11 import qualified Data.Text as T
12 import qualified Data.Text.IO as TIO
13
14 data Optionset = Optionset
15     { optVerbose        :: Bool
16     , optVersion        :: Bool
17     , optHelp           :: Bool
18     , optInputFiles     :: [String]
19     , optOutputFile     :: String
20     , optInputFormat    :: String
21     , optOutputFormat   :: String
22     , optStartDate      :: String
23     , optEndDate        :: String
24     }
25
26 defaultOpts :: Optionset
27 defaultOpts = Optionset
28     { optVerbose        = False
29     , optVersion        = False
30     , optHelp           = False
31     , optInputFiles     = []
32     , optOutputFile     = ""
33     , optInputFormat    = "%FT%T%z"
34     , optOutputFormat   = "%FT%T%z"
35     , optStartDate      = ""
36     , optEndDate        = ""
37     }
38
39 availableOptions :: [OptDescr (Optionset -> IO Optionset)]
40 availableOptions =
41     [ Option ['h']    ["help"]
42         (NoArg (\ _ -> putStrLn (usageInfo "Usage: diddohs [OPTION...]" availableOptions) >> exitSuccess))
43         "Display program help"
44     , Option ['v']    ["verbose"]
45         (NoArg (\ optset -> return optset { optVerbose = True }))
46         "More detailed output"
47     , Option ['V']    ["version"]
48         (NoArg (\ optset -> return optset { optVersion = True }))
49         "Display program version"
50     , Option ['f']    ["file"]
51         (ReqArg (\ arg optset -> return optset { optInputFiles = optInputFiles optset ++ [arg]}) "FILE" )
52         "Read from FILE"
53     , Option ['w']    ["output"]
54         (ReqArg (\ arg optset -> return optset { optOutputFile = arg }) "FILE")
55         "Write to FILE"
56     , Option ['i']    ["informat"]
57         (ReqArg (\ arg optset -> return optset { optInputFormat = arg }) "FORMAT")
58         "Timeformat used in input"
59     , Option ['o']    ["outformat"]
60         (ReqArg (\ arg optset -> return optset { optOutputFormat = arg }) "FORMAT")
61         "Timeformat used in output"
62     , Option ['s']    ["start"]
63         (ReqArg (\ arg optset -> return optset { optStartDate = arg }) "DATE")
64         "Start of reporting period"
65     , Option ['e']    ["end"]
66         (ReqArg (\ arg optset -> return optset { optEndDate = arg }) "DATE")
67         "End of reporting period"
68     ]
69
70 -- SECTION: Map of logentries to Map of Diddos
71 logentryMapToDiddoMap :: Map.Map UTCTime Diddo.LogEntry -> Map.Map UTCTime Diddo.Diddo
72 logentryMapToDiddoMap logmap = Map.mapWithKey toDddEntry logmap
73     where
74         toDddEntry key value    = Diddo.logToDiddo (precedingTimestamp key) value
75         precedingTimestamp x    = case Map.lookupLT x logmap of
76             Just (y,_)          -> y
77             Nothing             -> fst $ Map.findMin logmap
78 -- SECTION: Map of logentries to Map of DiddoEntries
79
80 getLoglines :: [String] -> IO [T.Text]
81 getLoglines []          = T.lines <$> TIO.getContents
82 getLoglines files@(_:_) = T.lines . T.concat <$> mapM TIO.readFile files
83
84 main :: IO ()
85 main = do
86     -- SECTION: option processing
87     (userOpts,args,errs) <-
88         getArgs >>= return . getOpt Permute availableOptions
89
90     unless (null errs) $ do
91         mapM_ (hPutStr stderr) errs
92         exitFailure
93
94     opts <- foldl (>>=) (return defaultOpts) userOpts
95
96     let
97         inDateFmt   = optInputFormat opts
98         outDateFmt  = optOutputFormat opts
99
100         startDate   = parseToZonedTime inDateFmt $ optStartDate opts
101         endDate     = parseToZonedTime inDateFmt $ optEndDate opts
102     -- SECTION: option processing
103
104     loglines <- getLoglines $ optInputFiles opts
105
106     let
107         timestampLogentryMap =
108             Map.fromList $ map Diddo.parseDiddoLogline loglines
109
110         (_, _, startedTimestampLogentryMap) =
111             Map.splitLookup (zonedTimeToUTC startDate) timestampLogentryMap
112
113         (endedTimestampLogentryMap, lastEntry, _) =
114             Map.splitLookup (zonedTimeToUTC endDate) startedTimestampLogentryMap
115
116         timestampDiddoMap =
117             logentryMapToDiddoMap timestampLogentryMap
118
119     -- DEBUG
120     mapM_ putStrLn args
121     -- DEBUG
122
123     mapM_ (TIO.putStrLn . snd) $ Map.toAscList $ Map.map (Diddo.formatDiddo outDateFmt) timestampDiddoMap
124