libstackexchange 0.2.0.0 → 0.2.1.0
raw patch · 3 files changed
+53/−5 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Network.StackExchange.Response: se :: (Functor f, Isomorphic k) => k (SE a -> f (SE a)) (Value -> f Value)
+ Network.StackExchange.Response: se :: (Functor f, Isomorphic k) => k (SE a -> f (SE a)) (Maybe Value -> f (Maybe Value))
Files
- libstackexchange.cabal +1/−1
- src/Network/StackExchange/API.hs +43/−0
- src/Network/StackExchange/Response.hs +9/−4
libstackexchange.cabal view
@@ -1,5 +1,5 @@ name: libstackexchange-version: 0.2.0.0+version: 0.2.1.0 synopsis: StackExchange API interface description: Provides interface for StackExchange v2.1 API homepage: https://github.com/supki/libstackexchange
src/Network/StackExchange/API.hs view
@@ -100,6 +100,8 @@ 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(("@@ -436,6 +438,10 @@ -- 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 =@@ -444,6 +450,10 @@ 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) =@@ -501,6 +511,10 @@ -- 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: ")@@ -797,6 +811,10 @@ 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]@@ -810,6 +828,11 @@ 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) =@@ -838,6 +861,11 @@ 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) =@@ -982,6 +1010,11 @@ -- 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) =@@ -999,12 +1032,22 @@ 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]
src/Network/StackExchange/Response.hs view
@@ -13,10 +13,11 @@ import Control.Applicative ((<$>)) import Control.Exception (Exception, throwIO)+import Data.Maybe (fromMaybe) import Data.Typeable (Typeable) import Control.Lens-import Data.Aeson (Value)+import Data.Aeson (Value(..)) import Data.ByteString.Lazy (ByteString, toStrict) import Data.Default (Default(..)) import Data.Text.Lazy.Encoding (encodeUtf8)@@ -47,6 +48,10 @@ SEException r "libstackexchange.askSE: no parsing function registered" --- | Isomorphism lens for the ease of interaction with generic aeson parser lenses-se ∷ (Functor f, Isomorphic k) ⇒ k (SE a → f (SE a)) (Value → f Value)-se = iso SE unSE+-- | Isomorphism for the ease of interaction with aeson-lens+se ∷ (Functor f, Isomorphic k) ⇒ k (SE a → f (SE a)) (Maybe Value → f (Maybe Value))+se = iso to' from'+ where+ to' = SE . fromMaybe Null+ from' (SE Null) = Nothing+ from' (SE x) = Just x