packages feed

advent-of-code-api 0.2.5.0 → 0.2.6.0

raw patch · 3 files changed

+59/−14 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Advent: aocServerTime :: IO LocalTime

Files

CHANGELOG.md view
@@ -1,6 +1,18 @@ Changelog ========= +Version 0.2.6.0+---------------++*December 3, 2019*++<https://github.com/mstksg/advent-of-code-api/releases/tag/v0.2.6.0>++*   Add `aocServerTime` to get the current time for AoC servers.+*   Fix cacheing rules for global leaderboard (was previously not saving or+    invalidating cache properly) also for prompt (will not invalidate+    part1-only caches if there is no session key)+ Version 0.2.5.0 --------------- 
advent-of-code-api.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 47b5a0fa5ec3911f9afa108c1f723d2716f225a23091507886305ff551fdca08+-- hash: 11039e11778c64e34a0031b4251a99a15470033e3dafd1962b1db1a02bcab593  name:           advent-of-code-api-version:        0.2.5.0+version:        0.2.6.0 synopsis:       Advent of Code REST API bindings and servant API description:    Haskell bindings for Advent of Code REST API and a servant API.  Please use                 responsibly! See README.md or "Advent" module for an introduction and
src/Advent.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE RecordWildCards    #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TupleSections      #-}+{-# LANGUAGE TypeApplications   #-} {-# LANGUAGE TypeInType         #-} {-# LANGUAGE ViewPatterns       #-} @@ -63,6 +64,7 @@   -- ** Day   , mkDay, mkDay_, dayInt, pattern DayInt, _DayInt   , aocDay+  , aocServerTime   -- ** Part   , partChar, partInt   -- ** Leaderboard@@ -138,12 +140,20 @@ data AoC :: Type -> Type where     -- | Fetch prompts for a given day.  Returns a 'Map' of 'Part's and     -- their associated promps, as HTML.+    --+    -- _Cacheing rules_: Is cached on a per-day basis.  An empty session+    -- key is given, it will be happy with only having Part 1 cached.  If+    -- a non-empty session key is given, it will trigger a cache+    -- invalidation on every request until both Part 1 and Part 2 are+    -- received.     AoCPrompt         :: Day         -> AoC (Map Part Text)      -- | Fetch input, as plaintext.  Returned verbatim.  Be aware that     -- input might contain trailing newlines.+    --+    -- /Cacheing rules/: Is cached forever, per day per session key.     AoCInput :: Day -> AoC Text      -- | Submit a plaintext answer (the 'String') to a given day and part.@@ -152,6 +162,8 @@     -- __WARNING__: Answers are not length-limited.  Answers are stripped     -- of leading and trailing whitespace and run through 'URI.encode'     -- before submitting.+    --+    -- /Cacheing rules/: Is never cached.     AoCSubmit         :: Day         -> Part@@ -174,6 +186,9 @@     -- you set up automation for this, please do not use it more than once     -- per day.     --+    -- /Cacheing rules/: Is never cached, so please use responsibly (see+    -- note above).+    --     -- @since 0.2.0.0     AoCLeaderboard         :: Integer@@ -186,7 +201,7 @@     -- when using this.  If you automate this, please do not fetch any more     -- often than necessary.     ---    -- Calls to this will be cached if a full leaderboard is observed.+    -- /Cacheing rules/: Will be cached if a full leaderboard is observed.     --     -- @since 0.2.3.0     AoCDailyLeaderboard@@ -200,7 +215,8 @@     -- when using this.  If you automate this, please do not fetch any more     -- often than necessary.     ---    -- Calls to this will be cached if fetched after each event ends.+    -- /Cacheing rules/: Will not cache if an event is ongoing, but will be+    -- cached if received after the event is over.     --     -- @since 0.2.3.0     AoCGlobalLeaderboard@@ -344,7 +360,10 @@           Just fp -> cacheing (cacheDir </> fp) $                        if _aForce                          then noCache-                         else saverLoader (not eventOver) a+                         else saverLoader+                                (not (null _aSessionKey))+                                (not eventOver)+                                a      cacher . runExceptT $ do       forM_ (aocDay a) $ \d -> do@@ -389,10 +408,11 @@   saverLoader-    :: Bool             -- ^ is the event ongoing (True) or over (False)?+    :: Bool             -- ^ is there a non-empty session token?+    -> Bool             -- ^ is the event ongoing (True) or over (False)?     -> AoC a     -> SaverLoader (Either AoCError a)-saverLoader evt = \case+saverLoader validToken evt = \case     AoCPrompt{} -> SL { _slSave = either (const Nothing) (Just . encodeMap)                       , _slLoad = \str ->                           let mp     = decodeMap str@@ -411,15 +431,20 @@             guard $ fullDailyBoard r             pure $ Right r         }-    AoCGlobalLeaderboard{}-      | evt       -> noCache-      | otherwise -> SL-          { _slSave = either (const Nothing) (Just . TL.toStrict . TL.decodeUtf8 . A.encode)-          , _slLoad = fmap Right . A.decode . TL.encodeUtf8 . TL.fromStrict-          }+    AoCGlobalLeaderboard{} -> SL+        { _slSave = either+                        (const Nothing)+                        (Just . TL.toStrict . TL.decodeUtf8 . A.encode @(Bool, GlobalLeaderboard) . (evt,))+        , _slLoad = \str -> do+            (evt', lb) <- A.decode @(Bool, GlobalLeaderboard) . TL.encodeUtf8 . TL.fromStrict $ str+            guard $ not evt'        -- only load cache if evt' is false: it was saved in a non-evt time+            pure $ Right lb+        }   where     expectedParts :: Set Part-    expectedParts = S.fromDistinctAscList [Part1 ..]+    expectedParts+      | validToken = S.singleton Part1+      | otherwise  = S.fromDistinctAscList [Part1 ..]     sep = ">>>>>>>>>"     encodeMap mp = T.intercalate "\n" . concat $                             [ maybeToList $ M.lookup Part1 mp@@ -454,6 +479,14 @@     -> UTCTime challengeReleaseTime y d = UTCTime (fromGregorian y 12 (fromIntegral (dayInt d)))                                    (5 * 60 * 60)++-- | Utility to get the current time on AoC servers.  Basically just gets the current+-- time in Eastern Standard Time.  This is only as accurate as your+-- machine's actual time --- it doesn't actually do anything networked.+--+-- @since 0.2.6.0+aocServerTime :: IO LocalTime+aocServerTime = utcToLocalTime (read "EST") <$> getCurrentTime  strip :: String -> String strip = T.unpack . T.strip . T.pack