reddit-0.2.0.0: src/Reddit/Actions/Comment.hs
-- | Contains comment-related actions, like editing comments
-- and performing moderator actions on posts.
module Reddit.Actions.Comment
( getNewComments
, getNewComments'
, getMoreChildren
, getCommentInfo
, getCommentsInfo
, editComment
, deleteComment
, removeComment ) where
import Reddit.Types.Comment
import Reddit.Types.Empty
import Reddit.Types.Error
import Reddit.Types.Listing
import Reddit.Types.Options
import Reddit.Types.Post
import Reddit.Types.Reddit
import Reddit.Types.Subreddit
import qualified Reddit.Routes as Route
import Data.Default.Class
import Data.Text (Text)
import Network.API.Builder (APIError(..))
-- | Get a 'CommentListing' for the most recent comments on the site overall.
-- This maps to <http://reddit.com/r/$SUBREDDIT/comments>, or <http://reddit.com/comments>
-- if the subreddit is not specified.
-- Note that none of the comments returned will have any child comments.
getNewComments :: Monad m => Maybe SubredditName -> RedditT m CommentListing
getNewComments = getNewComments' def
-- | Get a 'CommentListing' for the most recent comments with the specified 'Options' and
-- 'SubredditName'. Note that none of the comments returned will have any child comments.
-- If the 'Options' is 'def', then this function is identical to 'getNewComments'.
getNewComments' :: Monad m => Options CommentID -> Maybe SubredditName -> RedditT m CommentListing
getNewComments' opts r = runRoute $ Route.newComments opts r
-- | Expand children comments that weren't fetched on initial load.
-- Equivalent to the web UI's "load more comments" button.
getMoreChildren :: Monad m
=> PostID -- ^ @PostID@ for the top-level
-> [CommentID] -- ^ List of @CommentID@s to expand
-> RedditT m [CommentReference]
getMoreChildren _ [] = return []
getMoreChildren p cs = do
let (now, next) = splitAt 20 cs
POSTWrapped rs <- runRoute $ Route.moreChildren p now
more <- getMoreChildren p next
return $ rs ++ more
-- | Given a 'CommentID', 'getCommentInfo' will return the full details for that comment.
getCommentInfo :: Monad m => CommentID -> RedditT m Comment
getCommentInfo c = do
res <- getCommentsInfo [c]
case res of
Listing _ _ [comment] -> return comment
_ -> failWith $ APIError InvalidResponseError
-- | Given a list of 'CommentID's, 'getCommentsInfo' will return another list containing
-- the full details for all the comments. Note that Reddit's
-- API imposes a limitation of 100 comments per request, so this function will fail immediately if given a list of more than 100 IDs.
getCommentsInfo :: Monad m => [CommentID] -> RedditT m CommentListing
getCommentsInfo cs =
if null $ drop 100 cs
then do
res <- runRoute $ Route.commentsInfo cs
case res of
Listing _ _ comments | sameLength comments cs ->
return res
_ -> failWith $ APIError InvalidResponseError
else failWith $ APIError TooManyRequests
where
sameLength (_:xs) (_:ys) = sameLength xs ys
sameLength [] [] = True
sameLength _ _ = False
-- | Edit a comment.
editComment :: Monad m
=> CommentID -- ^ Comment to edit
-> Text -- ^ New comment text
-> RedditT m Comment
editComment thing text = do
POSTWrapped res <- runRoute $ Route.edit thing text
return res
-- | Deletes one of your own comments. Note that this is different from
-- removing a comment as a moderator action.
deleteComment :: Monad m => CommentID -> RedditT m ()
deleteComment = nothing . runRoute . Route.delete
-- | Removes a comment (as a moderator action). Note that this is different
-- from deleting a comment.
removeComment :: Monad m => CommentID -> RedditT m ()
removeComment = nothing . runRoute . Route.removePost False