reddit-0.1.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.Routes.Run
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 Control.Monad.IO.Class
import Data.Default
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 :: MonadIO 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' :: MonadIO 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 :: MonadIO 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 :: MonadIO 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 :: MonadIO 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 :: MonadIO 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 :: MonadIO 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 :: MonadIO m => CommentID -> RedditT m ()
removeComment = nothing . runRoute . Route.removePost False