summaryrefslogtreecommitdiff
path: root/lib/Postdelay/Scan.hs
diff options
context:
space:
mode:
authorGregor Kleen <aethoago@141.li>2017-01-30 13:33:33 +0100
committerGregor Kleen <aethoago@141.li>2017-01-30 13:33:33 +0100
commita45fa188046ab652150d332f48202f0e3fa5ea82 (patch)
tree36d54dbfb82f2127a86b105a27df34339e370d17 /lib/Postdelay/Scan.hs
parentf5d85473fc1f59dc63f184a118c08af02f025345 (diff)
downloadpostdelay-a45fa188046ab652150d332f48202f0e3fa5ea82.tar
postdelay-a45fa188046ab652150d332f48202f0e3fa5ea82.tar.gz
postdelay-a45fa188046ab652150d332f48202f0e3fa5ea82.tar.bz2
postdelay-a45fa188046ab652150d332f48202f0e3fa5ea82.tar.xz
postdelay-a45fa188046ab652150d332f48202f0e3fa5ea82.zip
Support a X-Timezone header
Diffstat (limited to 'lib/Postdelay/Scan.hs')
-rw-r--r--lib/Postdelay/Scan.hs27
1 files changed, 16 insertions, 11 deletions
diff --git a/lib/Postdelay/Scan.hs b/lib/Postdelay/Scan.hs
index fba9f35..2f0a78a 100644
--- a/lib/Postdelay/Scan.hs
+++ b/lib/Postdelay/Scan.hs
@@ -1,4 +1,4 @@
1{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, FlexibleContexts, RecordWildCards, ViewPatterns #-} 1{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, FlexibleContexts, RecordWildCards, ViewPatterns, TupleSections #-}
2 2
3module Postdelay.Scan 3module Postdelay.Scan
4 ( scan 4 ( scan
@@ -45,24 +45,29 @@ scan :: (MonadIO m, MonadError ParseError m) => String -> m (Maybe Delay)
45scan = fmap getOption . extractDelay <=< either throwError return . parse message "" 45scan = fmap getOption . extractDelay <=< either throwError return . parse message ""
46 46
47extractDelay :: forall m. (MonadIO m, MonadError ParseError m) => Message -> m (Option Delay) 47extractDelay :: forall m. (MonadIO m, MonadError ParseError m) => Message -> m (Option Delay)
48extractDelay (Message headers _) 48extractDelay (Message headers _) = do
49 = let latestCtx = maximumBy (comparing baseTime) dateHeaders 49 zones <- zoneHeaders
50 in foldMap pure <$> mapM (flip runReaderT latestCtx . parseDelay) delayHeaders 50 let (baseTime, dateTz) = maximumBy (comparing fst) dateHeaders
51 tz = foldr' (flip (<>)) (Left dateTz) zones
52 foldMap pure <$> mapM (flip runReaderT TimeCtx{..} . parseDelay) delayHeaders
51 where 53 where
52 delayHeaders :: [Field] 54 delayHeaders :: [Field]
53 delayHeaders = do 55 delayHeaders = do
54 (OptionalField field content) <- headers 56 (OptionalField field content) <- headers
55 guard $ CI.mk field == "X-Delay" 57 guard $ CI.mk field == "X-Delay"
56 return . OptionalField field $ decodeWords content 58 return . OptionalField field $ decodeWords content
57 dateHeaders :: [TimeCtx] 59 dateHeaders :: [(UTCTime, TimeZone)]
58 dateHeaders = do 60 dateHeaders = do
59 (Date CalendarTime{..}) <- headers 61 (Date CalendarTime{..}) <- headers
60 let tz = minutesToTimeZone . round $ ctTZ % 60 62 let tz = minutesToTimeZone . round $ ctTZ % 60
61 return $ TimeCtx 63 return . (, tz) . localTimeToUTC tz $ LocalTime
62 { baseTime = localTimeToUTC tz $ LocalTime 64 (fromGregorian (fromIntegral ctYear) (fromEnum ctMonth + 1) ctDay)
63 (fromGregorian (fromIntegral ctYear) (fromEnum ctMonth + 1) ctDay) 65 (TimeOfDay ctHour ctMin $ fromIntegral ctSec + fromIntegral ctPicosec * 1e-12)
64 (TimeOfDay ctHour ctMin $ fromIntegral ctSec + fromIntegral ctPicosec * 1e-12) 66 zoneHeaders :: m [Either TimeZone TZ]
65 , tz = Left tz 67 zoneHeaders = runListT $ do
66 } 68 (OptionalField field content) <- ListT $ return headers
69 guard $ CI.mk field == "X-Timezone"
70 Right r <- runParserT (spaces *> pTimeZone <* spaces <* eof) () field content
71 return r
67 parseDelay :: Field -> ReaderT TimeCtx m Delay 72 parseDelay :: Field -> ReaderT TimeCtx m Delay
68 parseDelay (OptionalField field content) = either throwError return =<< runParserT (Until <$> pTimeSpec) () field content 73 parseDelay (OptionalField field content) = either throwError return =<< runParserT (Until <$> pTimeSpec) () field content