libstackexchange-0.2.1.0: src/Network/StackExchange/API.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE ViewPatterns #-}
-- | API methods list
module Network.StackExchange.API
( -- * SE AccessToken
readAccessTokens, invalidateAccessTokens, applicationDeAuthenticate
-- * SE Answer
, answers, answersByIds, answersOnUsers
, answersOnQuestions, meAnswers, topUserAnswersInTags, meTagsTopAnswers
-- * SE Badge
, badges, badgesByIds, badgeRecipientsByIds
, badgesByName, badgeRecipients, badgesByTag
, badgesOnUsers, meBadges
-- * SE Comment
, commentsOnAnswers, comments, commentsByIds, deleteComment, editComment
, commentsOnPosts, createComment, commentsOnQuestions
, commentsOnUsers, meComments, commentsByUsersToUser, meCommentsTo
, mentionsOnUsers, meMentioned
-- * SE Error
, errors
-- * SE Event
, events
-- * SE Filter
, createFilter, readFilter
-- * SE InboxItems
, inbox, inboxUnread, userInbox, meInbox, userUnreadInbox, meUnreadInbox
-- * SE Info
, info
-- * SE NetworkUser
, associatedUsers, meAssociatedUsers
-- * SE AccountMerge
, mergeHistory, meMergeHistory
-- * SE Notification
, notifications, notificationsUnread, userNotifications, meNotifications
, userUnreadNotifications, meUnreadNotifications
-- * SE Post
, posts, postsByIds
-- * SE Privilege
, privileges, privilegesOnUsers, mePriviledges
-- * SE Question
, questions, questionsByIds, linkedQuestions, relatedQuestions
, featuredQuestions, unansweredQuestions, noAnswerQuestions
, search, advancedSearch, similar, faqsByTags, favoritesOnUsers
, meFavorites, questionsOnUsers, meQuestions, featuredQuestionsOnUsers
, meFeaturedQuestions, noAnswerQuestionsOnUsers, meNoAnswerQuestions
, unacceptedQuestionsOnUsers, meUnacceptedQuestions, unansweredQuestionsOnUsers
, meUnansweredQuestions, topUserQuestionsInTags, meTagsTopQuestions
-- * SE QuestionTimeline
, questionsTimeline
-- * SE Reputation
, reputationOnUsers, meReputation
-- * SE ReputationHistory
, reputationHistory, reputationHistoryFull
, meReputationHistory, meReputationHistoryFull
-- * SE Revision
, revisionsByIds, revisionsByGuids
-- * SE Site
, sites
-- * SE SuggestedEdit
, postsOnSuggestedEdits, suggestedEdits, suggestedEditsByIds
, suggestedEditsOnUsers, meSuggestedEdits
-- * SE Tag
, tags, moderatorOnlyTags, requiredTags
, tagsByName, relatedTags, tagsOnUsers, meTags
-- * SE TagScore
, topAnswerersOnTag, topAskersOnTag
-- * SE TagSynonym
, tagSynonyms, synonymsByTags
-- * SE TagWiki
, wikisByTags
-- * SE TopTag
, topAnswerTagsOnUsers, topQuestionTagsOnUsers
, meTopAnswerTags, meTopQuestionTags
-- * SE User
, users, usersByIds, me, moderators, electedModerators
-- * SE UserTimeline
, timelineOnUsers, meTimeline
-- * SE WritePermission
, writePermissions, meWritePermissions
) where
import Control.Applicative ((<$>))
import Data.Monoid ((<>))
import Control.Exception (throw)
import Control.Lens ((^.))
import Data.Aeson (Value)
import qualified Data.Aeson as A
import qualified Data.Aeson.Lens as L
import qualified Data.Attoparsec.Lazy as AP
import Data.ByteString.Lazy (ByteString)
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as T
import Data.Text.Lazy.Builder (toLazyText)
import Data.Text.Lazy.Builder.Int (decimal)
import Network.StackExchange.Response
import Network.StackExchange.Request
-- $setup
-- >>> import Control.Lens ((^.),(^..), from, to, traverse)
-- >>> import Data.Maybe (catMaybes, isJust)
-- >>> let pagesize = 10 :: Int
-- >>> let checkLengthM f = ((== pagesize) . length) `fmap` f
-- >>> let k = key "Lhg6xe5d5BvNK*C0S8jijA(("
-- >>> let s = site "stackoverflow"
-- >>> let q = query [("pagesize", "10")]
--------------------------
-- Access Tokens
--------------------------
-- | <https://api.stackexchange.com/docs/invalidate-access-tokens>
invalidateAccessTokens ∷ [Text] → Request a "invalidateAccessTokens" [SE AccessToken]
invalidateAccessTokens (T.intercalate ";" → ts) =
path ("access-tokens/" <> ts <> "/invalidate") <>
parse (attoparsec items ".access-tokens/{accessTokens}/invalidate: ")
-- | <https://api.stackexchange.com/docs/read-access-tokens>
readAccessTokens ∷ [Text] → Request a "readAccessTokens" [SE AccessToken]
readAccessTokens (T.intercalate ";" → ts) =
path ("access-tokens/" <> ts) <>
parse (attoparsec items ".access-tokens/{accessTokens}: ")
-- | <https://api.stackexchange.com/docs/application-de-authenticate>
applicationDeAuthenticate ∷ [Text] → Request a "applicationDeAuthenticate" [SE AccessToken]
applicationDeAuthenticate (T.intercalate ";" → ts) =
path ("apps/" <> ts <> "/de-authenticate") <>
parse (attoparsec items ".apps/{accessTokens}/de-authenticate: ")
--------------------------
-- Answers
--------------------------
-- $answers
-- >>> checkLengthM $ askSE (answers <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/answers>
answers ∷ Request a "answers" [SE Answer]
answers = path "answers" <> parse (attoparsec items ".answers: ")
-- $answersByIds
-- >>> length `fmap` askSE (answersByIds [6841479, 215422, 8881376] <> s <> k)
-- 3
-- | <https://api.stackexchange.com/docs/answers-by-ids>
answersByIds ∷ [Int] → Request a "answersByIds" [SE Answer]
answersByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("answers/" <> is) <> parse (attoparsec items ".answers/{ids}: ")
-- $answersOnUsers
-- >>> checkLengthM $ askSE (answersOnUsers [972985] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/answers-on-users>
answersOnUsers ∷ [Int] → Request a "answersOnUsers" [SE Answer]
answersOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/answers") <>
parse (attoparsec items ".users/{ids}/answers: ")
-- $answersOnQuestions
-- >>> checkLengthM $ askSE (answersOnQuestions [394601] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/answers-on-questions>
answersOnQuestions ∷ [Int] → Request a "answersOnQuestions" [SE Answer]
answersOnQuestions (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("questions/" <> is <> "/answers") <>
parse (attoparsec items ".questions/{ids}/answers: ")
-- | <https://api.stackexchange.com/docs/me-answers>
meAnswers ∷ Request RequireToken "meAnswers" [SE Answer]
meAnswers =
path "me/answers" <> parse (attoparsec items ".me/answers: ")
-- $topUserAnswersInTags
-- >>> checkLengthM $ askSE (topUserAnswersInTags 1097181 ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/top-user-answers-in-tags>
topUserAnswersInTags ∷ Int → [Text] → Request a "topUserAnswersInTags" [SE Answer]
topUserAnswersInTags (toLazyText . decimal → i) (T.intercalate ";" → ts) =
path ("users/" <> i <> "/tags/" <> ts <> "/top-answers") <>
parse (attoparsec items ".users/{id}/tags/{tags}/top-answers: ")
-- | <https://api.stackexchange.com/docs/me-tags-top-answers>
meTagsTopAnswers ∷ [Text] → Request RequireToken "meTagsTopAnswers" [SE Answer]
meTagsTopAnswers (T.intercalate ";" → ts) =
path ("me/tags/" <> ts <> "/top-answers") <>
parse (attoparsec items ".me/tags/{tags}/top-answers: ")
--------------------------
-- Badges
--------------------------
-- $badges
-- >>> checkLengthM $ askSE (badges <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/badges>
badges ∷ Request a "badges" [SE Badge]
badges = path "badges" <> parse (attoparsec items ".badges: ")
-- $badgesByIds
-- >>> length `fmap` askSE (badgesByIds [20] <> s <> k <> q)
-- 1
-- | <https://api.stackexchange.com/docs/badges-by-ids>
badgesByIds ∷ [Int] → Request a "badgesByIds" [SE Badge]
badgesByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("badges/" <> is) <> parse (attoparsec items ".badges/{ids}: ")
-- $badgeRecipientsByIds
-- >>> checkLengthM $ askSE (badgeRecipientsByIds [20] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/badge-recipients-by-ids>
badgeRecipientsByIds ∷ [Int] → Request a "badgeRecipientsByIds" [SE Badge]
badgeRecipientsByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("badges/" <> is <> "/recipients") <>
parse (attoparsec items ".badges/{ids}/recipients: ")
-- $badgesByName
-- >>> checkLengthM $ askSE (badgesByName <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/badges-by-name>
badgesByName ∷ Request a "badgesByName" [SE Badge]
badgesByName =
path ("badges" <> "/name") <> parse (attoparsec items ".badges/name: ")
-- $badgeRecipients
-- >>> checkLengthM $ askSE (badgeRecipients <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/badge-recipients>
badgeRecipients ∷ Request a "badgeRecipients" [SE Badge]
badgeRecipients =
path ("badges" <> "/recipients") <>
parse (attoparsec items ".badges/recipients: ")
-- $badgesByTag
-- >>> checkLengthM $ askSE (badgesByTag <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/badges-by-tag>
badgesByTag ∷ Request a "badgesByTag" [SE Badge]
badgesByTag =
path ("badges" <> "/tags") <> parse (attoparsec items ".badges/tags: ")
-- $badgesOnUsers
-- >>> checkLengthM $ askSE (badgesOnUsers [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/badges-on-users>
badgesOnUsers ∷ [Int] → Request a "badgesOnUsers" [SE Badge]
badgesOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/badges") <>
parse (attoparsec items ".users/{ids}/badges: ")
-- | <https://api.stackexchange.com/docs/me-badges>
meBadges ∷ Request RequireToken "meBadges" [SE Badge]
meBadges = path "me/badges" <> parse (attoparsec items ".me/badges: ")
--------------------------
-- Comments
--------------------------
-- $commentsOnAnswers
-- >>> checkLengthM $ askSE (commentsOnAnswers [394837] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/comments-on-answers>
commentsOnAnswers ∷ [Int] → Request a "commentsOnAnswers" [SE Comment]
commentsOnAnswers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("answers/" <> is <> "/comments") <>
parse (attoparsec items ".answers/{ids}/comments: ")
-- $comments
-- >>> checkLengthM $ askSE (comments <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/comments>
comments ∷ Request a "comments" [SE Comment]
comments = path "comments" <> parse (attoparsec items ".comments: ")
-- | <https://api.stackexchange.com/docs/delete-comment>
deleteComment ∷ Int → Request RequireToken "deleteComment" ()
deleteComment (toLazyText . decimal → i) =
path ("comments/" <> i <> "/delete")
-- | <https://api.stackexchange.com/docs/edit-comment>
editComment ∷ Int → Text → Request RequireToken "editComment" (SE Comment)
editComment (toLazyText . decimal → i) body =
path ("comments/" <> i <> "/edit") <>
query [("body", body)] <>
parse (attoparsec (fmap SE) ".comments/{id}/edit:")
-- $commentsByIds
-- >>> length `fmap` askSE (commentsByIds [1218390] <> s <> k)
-- 1
-- | <https://api.stackexchange.com/docs/comments-by-ids>
commentsByIds ∷ [Int] → Request a "commentsByIds" [SE Comment]
commentsByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("comments/" <> is) <> parse (attoparsec items ".comments/{ids}: ")
-- $commentsOnPosts
-- >>> checkLengthM $ askSE (commentsOnPosts [394837] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/comments-on-posts>
commentsOnPosts ∷ [Int] → Request a "commentsOnPosts" [SE Comment]
commentsOnPosts (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("posts/" <> is <> "/comments") <>
parse (attoparsec items ".posts/{ids}/comments: ")
-- | <https://api.stackexchange.com/docs/create-comment>
createComment ∷ Int → Text → Request RequireToken "createComment" (SE Comment)
createComment (toLazyText . decimal → i) body =
path ("posts/" <> i <> "/comments/add") <>
query [("body", body)] <>
parse (attoparsec (fmap SE) ".posts/{id}/comments/add:")
-- $commentsOnQuestions
-- >>> checkLengthM $ askSE (commentsOnQuestions [394601] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/comments-on-questions>
commentsOnQuestions ∷ [Int] → Request a "commentsOnQuestions" [SE Comment]
commentsOnQuestions (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("questions/" <> is <> "/comments") <>
parse (attoparsec items ".questions/{ids}/comments: ")
-- $commentsOnUsers
-- >>> checkLengthM $ askSE (commentsOnUsers [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/comments-on-users>
commentsOnUsers ∷ [Int] → Request a "commentsOnUsers" [SE Comment]
commentsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/comments") <>
parse (attoparsec items ".users/{ids}/comments: ")
-- | <https://api.stackexchange.com/docs/me-comments>
meComments ∷ Request RequireToken "meComments" [SE Comment]
meComments = path "me/comments" <> parse (attoparsec items ".me/comments: ")
-- $commentsByUsersToUser
-- >>> checkLengthM $ askSE (commentsByUsersToUser [230461,1011995,157360] 1097181 <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/comments-by-users-to-user>
commentsByUsersToUser ∷ [Int] → Int → Request a "commentsByUsersToUser" [SE Comment]
commentsByUsersToUser (T.intercalate ";" . map (toLazyText . decimal) → is)
(toLazyText . decimal → toid) =
path ("users/" <> is <> "/comments/" <> toid) <>
parse (attoparsec items ".users/{ids}/comments/{toid}: ")
-- | <https://api.stackexchange.com/docs/me-comments-to>
meCommentsTo ∷ Int → Request RequireToken "meCommentsTo" [SE Comment]
meCommentsTo (toLazyText . decimal → toid) =
path ("me/comments/" <> toid) <>
parse (attoparsec items ".me/comments/{toid}:")
-- $mentionsOnUsers
-- >>> checkLengthM $ askSE (mentionsOnUsers [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/mentions-on-users>
mentionsOnUsers ∷ [Int] → Request a "mentionsOnUsers" [SE Comment]
mentionsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/mentioned") <>
parse (attoparsec items ".users/{ids}/mentioned: ")
-- | <https://api.stackexchange.com/docs/me-mentioned>
meMentioned ∷ Request RequireToken "meMentioned" [SE Comment]
meMentioned = path "me/mentioned" <> parse (attoparsec items ".me/mentioned: ")
--------------------------
-- Errors
--------------------------
-- $errors
-- >>> checkLengthM $ askSE (errors <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/errors>
errors ∷ Request a "errors" [SE Error]
errors = path "errors" <> parse (attoparsec items ".errors: ")
--------------------------
-- Events
--------------------------
-- | <https://api.stackexchange.com/docs/events>
events ∷ Request RequireToken "events" [SE Event]
events = path "events" <> parse (attoparsec items ".events: ")
--------------------------
-- Filters
--------------------------
-- $createFilter
-- >>> (^. from se . L.key "items" . L.nth 0 . L.key "filter" . L.asText) <$> askSE (createFilter [] [] "none" <> k)
-- Just "none"
-- | <https://api.stackexchange.com/docs/create-filter>
createFilter ∷ [Text] → [Text] → Text → Request a "createFilter" (SE Filter)
createFilter (T.intercalate ";" → include) (T.intercalate ";" → exclude) base =
path "filter/create" <>
query [("include", include), ("exclude", exclude), ("base", base)] <>
parse (attoparsec (fmap SE) ".filter/create: ")
-- $readFilter
-- >>> (^.. traverse . from se . L.key "filter" . L.asText) <$> askSE (readFilter ["none"] <> k)
-- [Just "none"]
-- | <https://api.stackexchange.com/docs/read-filter>
readFilter ∷ [Text] → Request a "readFilter" [SE Filter]
readFilter (T.intercalate ";" → fs) =
path ("filters/" <> fs) <>
parse (attoparsec items ".filters/{filters}: ")
--------------------------
-- Inbox Items
--------------------------
-- | <https://api.stackexchange.com/docs/inbox>
inbox ∷ Request RequireToken "inbox" [SE InboxItem]
inbox =
path "inbox" <>
parse (attoparsec items ".inbox: ")
-- | <https://api.stackexchange.com/docs/inbox-unread>
inboxUnread ∷ Request RequireToken "inboxUnread" [SE InboxItem]
inboxUnread =
path "inbox/unread" <>
parse (attoparsec items ".inbox/unread: ")
-- | <https://api.stackexchange.com/docs/user-inbox>
userInbox ∷ Int → Request RequireToken "userInbox" [SE InboxItem]
userInbox (toLazyText . decimal → i) =
path ("users/" <> i <> "/inbox") <>
parse (attoparsec items ".users/{id}/inbox: ")
-- | <https://api.stackexchange.com/docs/me-inbox>
meInbox ∷ Request RequireToken "meInbox" [SE InboxItem]
meInbox =
path "me/inbox" <>
parse (attoparsec items ".me/inbox: ")
-- | <https://api.stackexchange.com/docs/user-unread-inbox>
userUnreadInbox ∷ Int → Request RequireToken "userUnreadInbox" [SE InboxItem]
userUnreadInbox (toLazyText . decimal → i) =
path ("users/" <> i <> "/inbox/unread") <>
parse (attoparsec items ".users/{id}/inbox/unread: ")
-- | <https://api.stackexchange.com/docs/me-unread-inbox>
meUnreadInbox ∷ Request RequireToken "meUnreadInbox" [SE InboxItem]
meUnreadInbox =
path "me/inbox/unread" <>
parse (attoparsec items ".me/inbox/unread: ")
--------------------------
-- Info
--------------------------
-- $info
-- >>> isJust . (^. from se . L.key "items" . L.nth 0 . L.key "total_users" . L.asDouble) <$> askSE (info <> s <> k)
-- True
-- | <https://api.stackexchange.com/docs/info>
info ∷ Request a "info" (SE Info)
info = path "info" <> parse (attoparsec (fmap SE) ".info: ")
--------------------------
-- Network Users
--------------------------
-- $associatedUsers
-- >>> length `fmap` askSE (associatedUsers [1097181] <> k)
-- 1
-- | <https://api.stackexchange.com/docs/associated-users>
associatedUsers ∷ [Int] → Request a "associatedUsers" [SE NetworkUser]
associatedUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/associated") <>
parse (attoparsec items ".users/{ids}/associated: ")
-- | <https://api.stackexchange.com/docs/me-associated-users>
meAssociatedUsers ∷ Request RequireToken "meAssociatedUsers" [SE NetworkUser]
meAssociatedUsers =
path "me/associated" <>
parse (attoparsec items ".me/associated: ")
--------------------------
-- Merge History
--------------------------
-- $mergeHistory
-- >>> ((>= 1) . length) `fmap` askSE (mergeHistory [14] <> k)
-- True
-- | <https://api.stackexchange.com/docs/merge-history>
mergeHistory ∷ [Int] → Request a "mergeHistory" [SE AccountMerge]
mergeHistory (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/merges") <>
parse (attoparsec items ".users/{ids}/merges: ")
-- | <https://api.stackexchange.com/docs/me-merge-history>
meMergeHistory ∷ Request RequireToken "meMergeHistory" [SE AccountMerge]
meMergeHistory =
path "me/merges" <>
parse (attoparsec items ".me/merges: ")
--------------------------
-- Notifications
--------------------------
-- | <https://api.stackexchange.com/docs/notifications>
notifications ∷ Request RequireToken "notifications" [SE Notification]
notifications = path "notifications" <> parse (attoparsec items ".notifications: ")
-- | <https://api.stackexchange.com/docs/notifications-unread>
notificationsUnread ∷ Request RequireToken "notificationsUnread" [SE Notification]
notificationsUnread = path "notifications/unread" <> parse (attoparsec items ".notifications/unread: ")
-- | <https://api.stackexchange.com/docs/user-notifications>
userNotifications ∷ Int → Request RequireToken "userNotifications" [SE Notification]
userNotifications (toLazyText . decimal → i) =
path ("users/" <> i <> "/notifications") <>
parse (attoparsec items ".users/{id}/notifications: ")
-- | <https://api.stackexchange.com/docs/me-notifications>
meNotifications ∷ Request RequireToken "meNotifications" [SE Notification]
meNotifications =
path "me/notifications" <>
parse (attoparsec items ".me/notifications: ")
-- | <https://api.stackexchange.com/docs/user-unread-notifications>
userUnreadNotifications ∷ Int → Request RequireToken "userUnreadNotifications" [SE Notification]
userUnreadNotifications (toLazyText . decimal → i) =
path ("users/" <> i <> "/notifications/unread") <>
parse (attoparsec items ".users/{id}/notifications/unread: ")
-- | <https://api.stackexchange.com/docs/me-unread-notifications>
meUnreadNotifications ∷ Request RequireToken "meUnreadNotifications" [SE Notification]
meUnreadNotifications =
path "me/notifications" <>
parse (attoparsec items ".me/notifications/unread: ")
--------------------------
-- Posts
--------------------------
-- $posts
-- >>> checkLengthM $ askSE (posts <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/posts>
posts ∷ Request a "posts" [SE Post]
posts = path "posts" <> parse (attoparsec items ".posts: ")
-- $postsByIds
-- >>> length `fmap` askSE (postsByIds [394601] <> s <> k)
-- 1
-- | <https://api.stackexchange.com/docs/posts-by-ids>
postsByIds ∷ [Int] → Request a "postsByIds" [SE Post]
postsByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("posts/" <> is) <> parse (attoparsec items ".posts/{ids}: ")
--------------------------
-- Privileges
--------------------------
-- $privileges
-- >>> checkLengthM $ askSE (privileges <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/privileges>
privileges ∷ Request a "privileges" [SE Privilege]
privileges = path "privileges" <> parse (attoparsec items ".privileges: ")
-- $privilegesOnUsers
-- >>> checkLengthM $ askSE (privilegesOnUsers 1097181 <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/privileges-on-users>
privilegesOnUsers ∷ Int → Request a "privilegesOnUsers" [SE Privilege]
privilegesOnUsers (toLazyText . decimal → i) =
path ("users/" <> i <> "/privileges") <>
parse (attoparsec items ".users/{ids}/privileges: ")
-- | <https://api.stackexchange.com/docs/me-privileges>
mePriviledges ∷ Request RequireToken "mePriviledges" [SE Privilege]
mePriviledges = path "me/privileges" <> parse (attoparsec items ".me/privileges: ")
--------------------------
-- Questions
--------------------------
-- $questions
-- >>> checkLengthM $ askSE (questions <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/questions>
questions ∷ Request a "questions" [SE Question]
questions = path "questions" <> parse (attoparsec items ".questions: ")
-- $questionsByIds
-- >>> length `fmap` askSE (questionsByIds [394601] <> s <> k)
-- 1
-- | <https://api.stackexchange.com/docs/questions-by-ids>
questionsByIds ∷ [Int] → Request a "questionsByIds" [SE Question]
questionsByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("questions/" <> is) <> parse (attoparsec items ".questions/{ids}: ")
-- $linkedQuestions
-- >>> checkLengthM $ askSE (linkedQuestions [394601] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/linked-questions>
linkedQuestions ∷ [Int] → Request a "linkedQuestions" [SE Question]
linkedQuestions (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("questions/" <> is <> "/linked") <>
parse (attoparsec items ".questions/{ids}/linked: ")
-- $relatedQuestions
-- >>> checkLengthM $ askSE (relatedQuestions [394601] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/related-questions>
relatedQuestions ∷ [Int] → Request a "relatedQuestions" [SE Question]
relatedQuestions (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("questions/" <> is <> "/related") <>
parse (attoparsec items ".questions/{ids}/related: ")
-- $featuredQuestions
-- >>> checkLengthM $ askSE (featuredQuestions <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/featured-questions>
featuredQuestions ∷ Request a "featuredQuestions" [SE Question]
featuredQuestions =
path "questions/featured" <> parse (attoparsec items ".questions/featured: ")
-- $unansweredQuestions
-- >>> checkLengthM $ askSE (unansweredQuestions <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/unanswered-questions>
unansweredQuestions ∷ Request a "unansweredQuestions" [SE Question]
unansweredQuestions =
path "questions/unanswered" <>
parse (attoparsec items ".questions/unanswered: ")
-- $noAnswerQuestions
-- >>> checkLengthM $ askSE (noAnswerQuestions <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/no-answer-questions>
noAnswerQuestions ∷ Request a "noAnswerQuestions" [SE Question]
noAnswerQuestions =
path "questions/no-answers" <>
parse (attoparsec items ".questions/no-answers: ")
-- $search
-- >>> checkLengthM $ askSE (search "why" ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/search>
search ∷ Text → [Text] → Request a "search" [SE Question]
search t (T.intercalate ";" → ts) =
path "search" <>
query [("intitle",t),("tagged",ts)] <>
parse (attoparsec items ".search: ")
-- $advancedSearch
-- >>> checkLengthM $ askSE (advancedSearch <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/advanced-search>
advancedSearch ∷ Request a "advancedSearch" [SE Question]
advancedSearch =
path "search/advanced" <> parse (attoparsec items ".search/advanced: ")
-- $similar
-- >>> checkLengthM $ askSE (similar "sublists of list" ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/similar>
similar ∷ Text → [Text] → Request a "similar" [SE Question]
similar t (T.intercalate ";" → ts) =
path "similar" <>
query [("title",t),("tagged",ts)] <>
parse (attoparsec items ".similar: ")
-- $faqsByTags
-- >>> checkLengthM $ askSE (faqsByTags ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/faqs-by-tags>
faqsByTags ∷ [Text] → Request a "faqsByTags" [SE Question]
faqsByTags (T.intercalate ";" → ts) =
path ("tags/" <> ts <> "/faq") <>
parse (attoparsec items ".tags/{tags}/faq: ")
-- $favoritesOnUsers
-- >>> checkLengthM $ askSE (favoritesOnUsers [9204] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/favorites-on-users>
favoritesOnUsers ∷ [Int] → Request a "favoritesOnUsers" [SE Question]
favoritesOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/favorites") <>
parse (attoparsec items ".users/{ids}/favorites: ")
-- | <https://api.stackexchange.com/docs/me-favorites>
meFavorites ∷ Request RequireToken "meFavorites" [SE Question]
meFavorites = path "me/favorites" <> parse (attoparsec items ".me/favorites: ")
-- $questionsOnUsers
-- >>> checkLengthM $ askSE (questionsOnUsers [9204] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/questions-on-users>
questionsOnUsers ∷ [Int] → Request a "questionsOnUsers" [SE Question]
questionsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/questions") <>
parse (attoparsec items ".users/{ids}/questions: ")
-- | <https://api.stackexchange.com/docs/me-questions>
meQuestions ∷ Request RequireToken "meQuestions" [SE Question]
meQuestions = path "me/questions" <> parse (attoparsec items ".me/questions: ")
-- $featuredQuestionsOnUsers
-- >>> fq <- (map truncate :: [Double] -> [Int]) . catMaybes . (^.. traverse . from se . L.key "owner" . L.key "user_id" . L.asDouble) <$> askSE (featuredQuestions <> s <> k <> q)
-- >>> checkLengthM $ askSE $ featuredQuestionsOnUsers fq <> s <> k <> q
-- True
-- | <https://api.stackexchange.com/docs/featured-questions-on-users>
featuredQuestionsOnUsers ∷ [Int] → Request a "featuredQuestionsOnUsers" [SE Question]
featuredQuestionsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/questions/featured") <>
parse (attoparsec items ".users/{ids}/questions/featured: ")
-- | <https://api.stackexchange.com/docs/me-featured-questions>
meFeaturedQuestions ∷ Request RequireToken "meFeaturedQuestions" [SE Question]
meFeaturedQuestions = path "me/questions/featured" <> parse (attoparsec items ".me/questions/featured: ")
-- $noAnswerQuestionsOnUsers
-- >>> naaq <- (map truncate :: [Double] -> [Int]) . catMaybes . (^.. traverse . from se . L.key "owner" . L.key "user_id" . L.asDouble) <$> askSE (noAnswerQuestions <> s <> k <> q)
-- >>> checkLengthM $ askSE (noAnswerQuestionsOnUsers naaq <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/no-answer-questions-on-users>
noAnswerQuestionsOnUsers ∷ [Int] → Request a "noAnswerQuestionsOnUsers" [SE Question]
noAnswerQuestionsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/questions/no-answers") <>
parse (attoparsec items ".users/{ids}/questions/no-answers: ")
-- | <https://api.stackexchange.com/docs/me-no-answer-questions>
meNoAnswerQuestions ∷ Request RequireToken "meNoAnswerQuestions" [SE Question]
meNoAnswerQuestions = path "me/questions/no-answers" <> parse (attoparsec items ".me/questions/no-answers: ")
-- $unacceptedQuestionsOnUsers
-- >>> null `fmap` askSE (unacceptedQuestionsOnUsers [570689] <> s <> k <> q)
-- False
--
-- | <https://api.stackexchange.com/docs/unaccepted-questions-on-users>
unacceptedQuestionsOnUsers ∷ [Int] → Request a "unacceptedQuestionsOnUsers" [SE Question]
unacceptedQuestionsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/questions/unaccepted") <>
parse (attoparsec items ".users/{ids}/questions/unaccepted: ")
-- | <https://api.stackexchange.com/docs/me-unaccepted-questions>
meUnacceptedQuestions ∷ Request RequireToken "meUnacceptedQuestions" [SE Question]
meUnacceptedQuestions = path "me/questions/unaccepted" <> parse (attoparsec items ".me/questions/unaccepted: ")
-- $unansweredQuestionsOnUsers
-- >>> uaq <- (map truncate :: [Double] -> [Int]) . catMaybes . (^.. traverse . from se . L.key "owner" . L.key "user_id" . L.asDouble) <$> askSE (unansweredQuestions <> s <> k <> q)
-- >>> checkLengthM $ askSE (unansweredQuestionsOnUsers uaq <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/unanswered-questions-on-users>
unansweredQuestionsOnUsers ∷ [Int] → Request a "unansweredQuestionsOnUsers" [SE Question]
unansweredQuestionsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/questions/unanswered") <>
parse (attoparsec items ".users/{ids}/questions/unanswered: ")
-- | <https://api.stackexchange.com/docs/me-unanswered-questions>
meUnansweredQuestions ∷ Request RequireToken "meUnansweredQuestions" [SE Question]
meUnansweredQuestions = path "me/questions/unanswered" <> parse (attoparsec items ".me/questions/unanswered: ")
-- $topUserQuestionsInTags
-- >>> checkLengthM $ askSE (topUserQuestionsInTags 570689 ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/top-user-questions-in-tags>
topUserQuestionsInTags ∷ Int → [Text] → Request a "topUserQuestionsInTags" [SE Question]
topUserQuestionsInTags (toLazyText . decimal → i) (T.intercalate ";" → ts) =
path ("users/" <> i <> "/tags/" <> ts <> "/top-questions") <>
parse (attoparsec items ".users/{id}/tags/{tags}/top-questions: ")
-- | <https://api.stackexchange.com/docs/me-tags-top-questions>
meTagsTopQuestions ∷ [Text] → Request RequireToken "meTagsTopQuestions" [SE Question]
meTagsTopQuestions (T.intercalate ";" → ts) =
path ("me/tags/" <> ts <> "/top-questions") <>
parse (attoparsec items ".me/tags/{tags}/top-questions: ")
--------------------------
-- Question Timelines
--------------------------
-- $questionsTimeline
-- >>> checkLengthM $ askSE (questionsTimeline [570689] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/questions-timeline>
questionsTimeline ∷ [Int] → Request a "questionsTimeline" [SE QuestionTimeline]
questionsTimeline (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("questions/" <> is <> "/timeline") <>
parse (attoparsec items ".questions/{ids}/timeline: ")
--------------------------
-- Reputation
--------------------------
-- $reputationOnUsers
-- >>> checkLengthM $ askSE (reputationOnUsers [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/reputation-on-users>
reputationOnUsers ∷ [Int] → Request a "reputationOnUsers" [SE Reputation]
reputationOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/reputation") <>
parse (attoparsec items ".users/{ids}/reputation: ")
-- | <https://api.stackexchange.com/docs/me-reputation>
meReputation ∷ Request RequireToken "meReputation" [SE Reputation]
meReputation = path "me/reputation" <> parse (attoparsec items ".me/reputation: ")
--------------------------
-- Reputation History
-------------------------
-- $reputationHistory
-- >>> checkLengthM $ askSE (reputationHistory [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/reputation-history>
reputationHistory ∷ [Int] → Request a "reputationHistory" [SE ReputationHistory]
reputationHistory (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/reputation-history") <>
parse (attoparsec items ".users/{ids}/reputation-history: ")
-- | <https://api.stackexchange.com/docs/me-reputation-history>
meReputationHistory ∷ Request RequireToken "meReputationHistory" [SE ReputationHistory]
meReputationHistory =
path "me/reputation-history" <>
parse (attoparsec items ".me/reputation-history: ")
-- | <https://api.stackexchange.com/docs/full-reputation-history>
reputationHistoryFull ∷ [Int] → Request RequireToken "reputationHistoryFull" [SE ReputationHistory]
reputationHistoryFull (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/reputation-history/full") <>
parse (attoparsec items ".users/{ids}/reputation-history/full: ")
-- | <https://api.stackexchange.com/docs/me-full-reputation-history>
meReputationHistoryFull ∷ Request RequireToken "meReputationHistoryFull" [SE ReputationHistory]
meReputationHistoryFull =
path "me/reputation-history/full" <>
parse (attoparsec items ".me/reputation-history/full: ")
--------------------------
-- Revisions
--------------------------
-- $revisionsByIds
-- >>> checkLengthM $ askSE (revisionsByIds [1218390] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/revisions-by-ids>
revisionsByIds ∷ [Int] → Request a "revisionsByIds" [SE Revision]
revisionsByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("posts/" <> is <> "/revisions") <>
parse (attoparsec items ".posts/{ids}/revisions: ")
-- $revisionsByGuids
-- >>> length `fmap` askSE (revisionsByGuids ["881687CA-9A98-46CC-B9F0-4063322B5E2F"] <> s <> k <> q)
-- 1
-- | <https://api.stackexchange.com/docs/revisions-by-guids>
revisionsByGuids ∷ [Text] → Request a "revisionsByGuids" [SE Revision]
revisionsByGuids (T.intercalate ";" → is) =
path ("revisions/" <> is) <>
parse (attoparsec items ".revisions/{ids}: ")
--------------------------
-- Sites
--------------------------
-- $sites
-- >>> checkLengthM $ askSE (sites <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/sites>
sites ∷ Request a "sites" [SE Site]
sites = path "sites" <> parse (attoparsec items ".sites: ")
--------------------------
-- Suggested Edits
--------------------------
-- $postsOnSuggestedEdits
-- >>> se' <- (map truncate :: [Double] -> [Int]) . catMaybes . (^.. traverse . from se . L.key "post_id" . L.asDouble) <$> askSE (suggestedEdits <> s <> k <> q)
-- >>> checkLengthM $ askSE (postsOnSuggestedEdits se' <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/posts-on-suggested-edits>
postsOnSuggestedEdits ∷ [Int] → Request a "postsOnSuggestedEdits" [SE SuggestedEdit]
postsOnSuggestedEdits (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("posts/" <> is <> "/suggested-edits") <>
parse (attoparsec items ".posts/{ids}/suggested-edits: ")
-- $suggestedEdits
-- >>> checkLengthM $ askSE (suggestedEdits <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/suggested-edits>
suggestedEdits ∷ Request a "suggestedEdits" [SE SuggestedEdit]
suggestedEdits =
path "suggested-edits" <> parse (attoparsec items ".suggested-edits: ")
-- $suggestedEditsByIds
-- >>> se' <- (map truncate :: [Double] -> [Int]) . catMaybes . (^.. traverse . from se . L.key "suggested_edit_id" . L.asDouble) <$> askSE (suggestedEdits <> s <> k <> q)
-- >>> checkLengthM $ askSE (suggestedEditsByIds se' <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/suggested-edits-by-ids>
suggestedEditsByIds ∷ [Int] → Request a "suggestedEditsByIds" [SE SuggestedEdit]
suggestedEditsByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("suggested-edits/" <> is ) <>
parse (attoparsec items ".suggested-edits/{ids}: ")
-- $suggestedEditsOnUsers
-- >>> se' <- (map truncate :: [Double] -> [Int]) . catMaybes . (^.. traverse . from se . L.key "proposing_user" . L.key "user_id" . L.asDouble) <$> askSE (suggestedEdits <> s <> k <> q)
-- >>> checkLengthM $ askSE (suggestedEditsOnUsers se' <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/suggested-edits-on-users>
suggestedEditsOnUsers ∷ [Int] → Request a "suggestedEditsOnUsers" [SE SuggestedEdit]
suggestedEditsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/suggested-edits") <>
parse (attoparsec items ".users/{ids}/suggested-edits: ")
-- | <https://api.stackexchange.com/docs/me-suggested-edits>
meSuggestedEdits ∷ Request RequireToken "meSuggestedEdits" [SE SuggestedEdit]
meSuggestedEdits =
path "me/suggested-edits" <>
parse (attoparsec items ".me/suggested-edits: ")
--------------------------
-- Tags
--------------------------
-- $tags
-- >>> checkLengthM $ askSE (tags <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/tags>
tags ∷ Request a "tags" [SE Tag]
tags = path "tags" <> parse (attoparsec items ".tags: ")
-- $moderatorOnlyTags
-- >>> checkLengthM $ askSE (moderatorOnlyTags <> site "meta.serverfault" <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/moderator-only-tags>
moderatorOnlyTags ∷ Request a "moderatorOnlyTags" [SE Tag]
moderatorOnlyTags =
path "tags/moderator-only" <>
parse (attoparsec items ".tags/moderator-only: ")
-- $requiredTags
-- >>> (( > 0) . length) `fmap` askSE (requiredTags <> site "meta.serverfault" <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/required-tags>
requiredTags ∷ Request a "requiredTags" [SE Tag]
requiredTags =
path "tags/required" <> parse (attoparsec items ".tags/required: ")
-- $tagsByName
-- >>> ((> 0) . length) `fmap` askSE (tagsByName ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/tags-by-name>
tagsByName ∷ [Text] → Request a "tagsByName" [SE Tag]
tagsByName (T.intercalate ";" → ts) =
path ("tags/" <> ts <> "/info") <>
parse (attoparsec items ".tags/{tags}/info: ")
-- $relatedTags
-- >>> checkLengthM $ askSE (relatedTags ["haskell"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/related-tags>
relatedTags ∷ [Text] → Request a "relatedTags" [SE Tag]
relatedTags (T.intercalate ";" → ts) =
path ("tags/" <> ts <> "/related") <>
parse (attoparsec items ".tags/{tags}/related: ")
-- $tagsOnUsers
-- >>> checkLengthM $ askSE (tagsOnUsers [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/tags-on-users>
tagsOnUsers ∷ [Int] → Request a "tagsOnUsers" [SE Tag]
tagsOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/tags") <>
parse (attoparsec items ".users/{ids}/tags: ")
-- | <https://api.stackexchange.com/docs/me-tags>
meTags ∷ Request RequireToken "meTags" [SE Tag]
meTags = path "me/tags" <> parse (attoparsec items ".me/tags: ")
--------------------------
-- Tag Scores
--------------------------
-- $topAnswerersOnTag
-- >>> checkLengthM $ askSE (topAnswerersOnTag "haskell" "Month" <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/top-answerers-on-tags>
topAnswerersOnTag ∷ Text → Text → Request a "topAnswerersOnTag" [SE TagScore]
topAnswerersOnTag t p =
path ("tags/" <> t <> "/top-answerers/" <> p) <>
parse (attoparsec items ".tags/{tag}/top-answerers/{period}: ")
-- $topAskersOnTag
-- >>> checkLengthM $ askSE (topAskersOnTag "haskell" "Month" <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/top-askers-on-tags>
topAskersOnTag ∷ Text → Text → Request a "topAskersOnTag" [SE TagScore]
topAskersOnTag t p =
path ("tags/" <> t <> "/top-askers/" <> p) <>
parse (attoparsec items ".tags/{tag}/top-askers/{period}: ")
--------------------------
-- Tag Synonyms
--------------------------
-- $tagSynonyms
-- >>> checkLengthM $ askSE (tagSynonyms <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/tag-synonyms>
tagSynonyms ∷ Request a "tagSynonyms" [SE TagSynonym]
tagSynonyms =
path "tags/synonyms" <> parse (attoparsec items ".tags/synonyms: ")
-- $synonymsByTags
-- >>> checkLengthM $ askSE (synonymsByTags ["iphone","java"] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/synonyms-by-tags>
synonymsByTags ∷ [Text] → Request a "synonymsByTags" [SE TagSynonym]
synonymsByTags (T.intercalate ";" → ts) =
path ("tags/" <> ts <> "/synonyms") <>
parse (attoparsec items ".tags/{tags}/synonyms: ")
--------------------------
-- Tag Wikis
--------------------------
-- $wikisByTags
-- >>> length `fmap` askSE (wikisByTags ["haskell"] <> s <> k <> q)
-- 1
-- | <https://api.stackexchange.com/docs/wikis-by-tags>
wikisByTags ∷ [Text] → Request a "wikisByTags" [SE TagWiki]
wikisByTags (T.intercalate ";" → ts) =
path ("tags/" <> ts <> "/wikis") <>
parse (attoparsec items ".tags/{tags}/wikis: ")
--------------------------
-- Top Tags
--------------------------
-- $topAnswerTagsOnUsers
-- >>> checkLengthM $ askSE (topAnswerTagsOnUsers 1097181 <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/top-answer-tags-on-users>
topAnswerTagsOnUsers ∷ Int → Request a "topAnswerTagsOnUsers" [SE TopTag]
topAnswerTagsOnUsers (toLazyText . decimal → i) =
path ("users/" <> i <> "/top-answer-tags") <>
parse (attoparsec items ".users/{id}/top-answer-tags: ")
-- | <https://api.stackexchange.com/docs/me-top-answer-tags>
meTopAnswerTags ∷ Request RequireToken "meTopAnswerTags" [SE TopTag]
meTopAnswerTags = path "me/top-answer-tags" <> parse (attoparsec items ".me/top-answer-tags: ")
-- $topQuestionTagsOnUsers
-- >>> checkLengthM $ askSE (topQuestionTagsOnUsers 570689 <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/top-question-tags-on-users>
topQuestionTagsOnUsers ∷ Int → Request a "topQuestionTagsOnUsers" [SE TopTag]
topQuestionTagsOnUsers (toLazyText . decimal → i) =
path ("users/" <> i <> "/top-question-tags") <>
parse (attoparsec items ".users/{id}/top-question-tags: ")
-- | <https://api.stackexchange.com/docs/me-top-question-tags>
meTopQuestionTags ∷ Request RequireToken "meTopQuestionTags" [SE TopTag]
meTopQuestionTags = path "me/top-question-tags" <> parse (attoparsec items ".me/top-question-tags: ")
--------------------------
-- Users
--------------------------
-- $users
-- >>> checkLengthM $ askSE (users <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/users>
users ∷ Request a "users" [SE User]
users = path "users" <> parse (attoparsec items ".users: ")
-- $users
-- >>> length `fmap` askSE (usersByIds [1097181] <> s <> k <> q)
-- 1
-- | <https://api.stackexchange.com/docs/users-by-ids>
usersByIds ∷ [Int] → Request a "usersByIds" [SE User]
usersByIds (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is) <> parse (attoparsec items ".users/{ids}: ")
-- | <https://api.stackexchange.com/docs/me>
me ∷ Request RequireToken "me" (SE User)
me = path "me" <> parse (head . attoparsec items ".me: ")
-- $moderators
-- >>> checkLengthM $ askSE (moderators <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/moderators>
moderators ∷ Request a "moderators" [SE User]
moderators =
path "users/moderators" <> parse (attoparsec items ".users/moderators: ")
-- $electedModerators
-- >>> checkLengthM $ askSE (electedModerators <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/elected-moderators>
electedModerators ∷ Request a "electedModerators" [SE User]
electedModerators =
path "users/moderators/elected" <>
parse (attoparsec items ".users/moderators/elected: ")
--------------------------
-- User Timeline
--------------------------
-- $timelineOnUsers
-- >>> checkLengthM $ askSE (timelineOnUsers [1097181] <> s <> k <> q)
-- True
-- | <https://api.stackexchange.com/docs/timeline-on-users>
timelineOnUsers ∷ [Int] → Request a "timelineOnUsers" [SE UserTimeline]
timelineOnUsers (T.intercalate ";" . map (toLazyText . decimal) → is) =
path ("users/" <> is <> "/timeline") <>
parse (attoparsec items ".users/{ids}/timeline: ")
-- | <https://api.stackexchange.com/docs/me-timeline>
meTimeline ∷ Request RequireToken "meTimeline" [SE UserTimeline]
meTimeline = path "me/timeline" <> parse (attoparsec items ".me/timeline: ")
--------------------------
-- Write Permissions
--------------------------
-- $writePermissions
-- >>> length `fmap` askSE (writePermissions 1097181 <> s <> k <> q)
-- 1
-- | <https://api.stackexchange.com/docs/write-permissions>
writePermissions ∷ Int → Request a "writePermissions" [SE WritePermission]
writePermissions (toLazyText . decimal → i) =
path ("users/" <> i <> "/write-permissions") <>
parse (attoparsec items ".users/{id}/write-permissions: ")
-- | <https://api.stackexchange.com/docs/me-write-permissions>
meWritePermissions ∷ Request RequireToken "meWritePermissions" [SE WritePermission]
meWritePermissions = path "me/write-permissions" <> parse (attoparsec items ".me/write-permissions: ")
attoparsec ∷ (Maybe Value → Maybe b) → String → ByteString → b
attoparsec f msg request = case AP.eitherResult $ AP.parse A.json request of
Right s → case f (Just s) of
Just b → b
Nothing → throw $ SEException request ("libstackexchange" ++ msg ++ "incorrect JSON content")
Left e → throw $ SEException request ("libstackexchange" ++ msg ++ e)
items ∷ Maybe Value → Maybe [SE a]
items s = map SE <$> (s ^. L.key "items")