]> git.netwichtig.de Git - user/henk/code/haskell/diddohs.git/blob - src/Main.hs
deleted: Diddo/Entry.hs
[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 Opt = Opt
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 :: Opt
27 defaultOpts = Opt
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 (Opt -> IO Opt)]
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 (\ opts -> return opts { optVerbose = True }))
46         "More detailed output"
47     , Option ['V']    ["version"]
48         (NoArg (\ opts -> return opts { optVersion = True }))
49         "Display program version"
50     , Option ['f']    ["file"]
51         (ReqArg (\ arg opts -> return opts { optInputFiles = optInputFiles opts ++ [arg]}) "FILE" )
52         "Read from FILE"
53     , Option ['w']    ["output"]
54         (ReqArg (\ arg opts -> return opts { optOutputFile = arg }) "FILE")
55         "Write to FILE"
56     , Option ['i']    ["informat"]
57         (ReqArg (\ arg opts -> return opts { optInputFormat = arg }) "FORMAT")
58         "Timeformat used in input"
59     , Option ['o']    ["outformat"]
60         (ReqArg (\ arg opts -> return opts { optOutputFormat = arg }) "FORMAT")
61         "Timeformat used in output"
62     , Option ['s']    ["start"]
63         (ReqArg (\ arg opts -> return opts { optStartDate = arg }) "DATE")
64         "Start of reporting period"
65     , Option ['e']    ["end"]
66         (ReqArg (\ arg opts -> return opts { 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 main :: IO ()
81 main = do
82     -- SECTION: option processing
83     (givenOptions,args,errs) <- getArgs >>= return . getOpt Permute availableOptions
84
85     unless (null errs) $ do
86         mapM_ (hPutStr stderr) errs
87         exitFailure
88
89     effectiveOptions <- foldl (>>=) (return defaultOpts) givenOptions
90
91     let
92         inDateFmt               = optInputFormat effectiveOptions
93         outDateFmt              = optOutputFormat effectiveOptions
94
95         startDate               = parseToZonedTime inDateFmt $ optStartDate effectiveOptions
96         endDate                 = parseToZonedTime inDateFmt $ optEndDate effectiveOptions
97     -- SECTION: option processing
98
99     loglines <- case optInputFiles effectiveOptions of
100             files@(_:_)     -> T.lines . T.concat <$> mapM TIO.readFile files
101             []              -> T.lines <$> TIO.getContents
102
103     let
104         timestampLogentryMap                        = Map.fromList $ map Diddo.parseDiddoLogline loglines
105         (_, _, startedTimestampLogentryMap)         = Map.splitLookup (zonedTimeToUTC startDate) timestampLogentryMap
106         (endedTimestampLogentryMap, lastEntry, _)   = Map.splitLookup (zonedTimeToUTC endDate) startedTimestampLogentryMap
107         timestampDiddoMap                           = logentryMapToDiddoMap timestampLogentryMap
108
109     -- DEBUG
110     mapM_ putStrLn args
111     -- DEBUG
112
113     mapM_ (TIO.putStrLn . snd) $ Map.toAscList $ Map.map (Diddo.formatDiddo outDateFmt) timestampDiddoMap
114