Copyright | (c) Justin Le 2019 |
---|---|
License | BSD3 |
Maintainer | justin@jle.im |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Haskell bindings for Advent of Code 2018 API. Caches and throttles requests automatically.
Specify your requests with AoC
and AoCOpts
, and run them with
runAoC
.
Examples:
-- Fetch prompts for day 5runAoC
myOpts $AoCPrompt
(mkDay_
5) -- Fetch input for day 8runAoC
myOpts $AoCInput
(mkDay_
8) -- Submit answer "hello" for Day 10, Part 1runAoC
myOpts $AoCSubmit
(mkDay_
10)Part1
"hello"
Please use responsibly. All actions are by default rate limited to one per three seconds, but this can be adjusted to a hard-limited cap of one per second.
Synopsis
- data AoC :: Type -> Type where
- data Part
- newtype Day = Day {}
- data AoCOpts = AoCOpts {}
- data SubmitRes
- = SubCorrect (Maybe Integer)
- | SubIncorrect Int (Maybe String)
- | SubWait Int
- | SubInvalid
- | SubUnknown String
- showSubmitRes :: SubmitRes -> String
- data Leaderboard = LB {}
- data LeaderboardMember = LBM {
- lbmGlobalScore :: Integer
- lbmName :: Maybe Text
- lbmLocalScore :: Integer
- lbmId :: Integer
- lbmLastStarTS :: Maybe UTCTime
- lbmStars :: Int
- lbmCompletion :: Map Day (Map Part UTCTime)
- runAoC :: AoCOpts -> AoC a -> IO (Either AoCError a)
- defaultAoCOpts :: Integer -> String -> AoCOpts
- data AoCError
- challengeReleaseTime :: Integer -> Day -> UTCTime
- timeToRelease :: Integer -> Day -> IO NominalDiffTime
- challengeReleased :: Integer -> Day -> IO Bool
- mkDay :: Integer -> Maybe Day
- mkDay_ :: Integer -> Day
- dayInt :: Day -> Integer
- aocDay :: AoC a -> Maybe Day
- partChar :: Part -> Char
- partInt :: Part -> Int
- setAoCThrottleLimit :: Int -> IO ()
- getAoCThrottleLimit :: IO Int
- aocReq :: Integer -> AoC a -> ClientM a
- aocBase :: BaseUrl
API
data AoC :: Type -> Type where Source #
An API command. An
an AoC API request that returns
results of type AoC
aa
.
A lot of these commands take Day
, which represents a day of December
up to and including Christmas Day (December 25th). You can convert an
integer day (1 - 25) into a Day
using mkDay
or mkDay_
.
AoCPrompt :: Day -> AoC (Map Part Text) | Fetch prompts for a given day. Returns a |
AoCInput :: Day -> AoC Text | Fetch input, as plaintext. Returned verbatim. Be aware that input might contain trailing newlines. |
AoCSubmit :: Day -> Part -> String -> AoC (Text, SubmitRes) | Submit a plaintext answer (the WARNING: Answers are not length-limited. Answers are stripped
of leading and trailing whitespace and run through |
AoCLeaderboard :: Integer -> AoC Leaderboard | Fetch the leaderboard for a given leaderboard public code (owner member ID). Requires session key. The public code can be found in the URL of the leaderboard: https://adventofcode.com/2019/leaderboard/private/view/12345 (the NOTE: This is the most expensive and taxing possible API call, and makes up the majority of bandwidth to the Advent of Code servers. As a courtesy to all who are participating in Advent of Code, please use this super respectfully, especially in December: if you set up automation for this, please do not use it more than once per day. Since: 0.2.0.0 |
A given part of a problem. All Advent of Code challenges are two-parts.
You can usually get Part1
(if it is already released) with a nonsense
session key, but Part2
always requires a valid session key.
Note also that Challenge #25 typically only has a single part.
Instances
Bounded Part Source # | |
Enum Part Source # | |
Eq Part Source # | |
Ord Part Source # | |
Read Part Source # | |
Show Part Source # | |
Generic Part Source # | |
FromJSON Part Source # | |
FromJSONKey Part Source # | |
Defined in Advent.API | |
ToHttpApiData Part Source # | |
Defined in Advent.API toUrlPiece :: Part -> Text # toEncodedUrlPiece :: Part -> Builder # toHeader :: Part -> ByteString # toQueryParam :: Part -> Text # | |
type Rep Part Source # | |
Describes the day: a number between 1 and 25 inclusive.
Represented by a Finite
ranging from 0 to 24 inclusive; you should
probably make one using the smart constructor mkDay
.
Instances
Bounded Day Source # | |
Enum Day Source # | |
Eq Day Source # | |
Ord Day Source # | |
Show Day Source # | |
Generic Day Source # | |
FromJSON Day Source # | |
FromJSONKey Day Source # | |
Defined in Advent.API | |
ToHttpApiData Day Source # | |
Defined in Advent.API toUrlPiece :: Day -> Text # toEncodedUrlPiece :: Day -> Builder # toHeader :: Day -> ByteString # toQueryParam :: Day -> Text # | |
type Rep Day Source # | |
Defined in Advent.API |
Setings for running an API request.
Session keys are required for all commands, but if you enter a bogus key
you should be able to get at least Part 1 from AoCPrompt
.
The session key can be found by logging in on a web client and checking the cookies. You can usually check these with in-browser developer tools.
Throttling is hard-limited to a minimum of 1 second between calls. Please be respectful and do not try to bypass this.
AoCOpts | |
|
Instances
Show AoCOpts Source # | |
Generic AoCOpts Source # | |
type Rep AoCOpts Source # | |
Defined in Advent type Rep AoCOpts = D1 (MetaData "AoCOpts" "Advent" "advent-of-code-api-0.2.2.1-inplace" False) (C1 (MetaCons "AoCOpts" PrefixI True) ((S1 (MetaSel (Just "_aSessionKey") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 String) :*: S1 (MetaSel (Just "_aYear") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Integer)) :*: (S1 (MetaSel (Just "_aCache") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe FilePath)) :*: (S1 (MetaSel (Just "_aForce") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Bool) :*: S1 (MetaSel (Just "_aThrottle") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Int))))) |
The result of a submission.
SubCorrect (Maybe Integer) | Correct submission, including global rank (if reported, which usually happens if rank is under 1000) |
SubIncorrect Int (Maybe String) | Incorrect submission. Contains the number of seconds you must
wait before trying again. The |
SubWait Int | Submission was rejected because an incorrect submission was recently submitted. Contains the number of seconds you must wait before trying again. |
SubInvalid | Submission was rejected because it was sent to an invalid question or part. Usually happens if you submit to a part you have already answered or have not yet unlocked. |
SubUnknown String | Could not parse server response. Contains parse error. |
Instances
data Leaderboard Source #
Leaderboard type, representing private leaderboard information.
Instances
data LeaderboardMember Source #
Leaderboard position for a given member.
LBM | |
|
Instances
defaultAoCOpts :: Integer -> String -> AoCOpts Source #
Sensible defaults for AoCOpts
for a given year and session key.
Use system temporary directory as cache, and throttle requests to one request per three seconds.
A possible (syncronous, logical, pure) error returnable from runAoC
.
Does not cover any asynchronous or IO errors.
AoCClientError ClientError | An error in the http request itself Note that if you are building this with servant-client-core <= 0.16,
this will contain |
AoCReleaseError NominalDiffTime | Tried to interact with a challenge that has not yet been released. Contains the amount of time until release. |
AoCThrottleError | The throttler limit is full. Either make less requests, or adjust
it with |
Instances
Show AoCError Source # | |
Generic AoCError Source # | |
Exception AoCError Source # | |
Defined in Advent toException :: AoCError -> SomeException # fromException :: SomeException -> Maybe AoCError # displayException :: AoCError -> String # | |
type Rep AoCError Source # | |
Defined in Advent type Rep AoCError = D1 (MetaData "AoCError" "Advent" "advent-of-code-api-0.2.2.1-inplace" False) (C1 (MetaCons "AoCClientError" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 ClientError)) :+: (C1 (MetaCons "AoCReleaseError" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 NominalDiffTime)) :+: C1 (MetaCons "AoCThrottleError" PrefixI False) (U1 :: Type -> Type))) |
Calendar
:: Integer | year |
-> Day | day |
-> IO NominalDiffTime |
Get time until release of a given challenge.
Check if a challenge has been released yet.
Utility
Day
aocDay :: AoC a -> Maybe Day Source #
Get the day associated with a given API command, if there is one.
Part
Throttler
setAoCThrottleLimit :: Int -> IO () Source #
Set the internal throttler maximum queue capacity. Default is 100.
getAoCThrottleLimit :: IO Int Source #
Get the internal throttler maximum queue capacity.