reddit-pub/reddit_pub/src/Network/Reddit.hs

47 lines
1.6 KiB
Haskell
Raw Normal View History

2021-10-25 19:04:24 +03:00
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
2021-10-27 21:10:22 +03:00
module Network.Reddit where
2021-10-25 19:04:24 +03:00
import Control.Lens
import Data.Aeson (FromJSON, ToJSON, Value)
import Data.Aeson.Lens
import Data.Config
import Data.SubReddit
import Data.Text (Text)
import Network.Wreq hiding (getWith)
import Network.Wreq.Session (Session, getWith)
import Pipes (Producer, (>->), for, runEffect)
import qualified Pipes.Prelude as P
2022-05-16 21:42:11 +03:00
import Reddit.Publish
2021-10-25 19:04:24 +03:00
import Data.Maybe (maybeToList)
import Control.Monad.Trans (liftIO)
2021-10-27 23:21:09 +03:00
import Database.SQLite.Simple.ToField (ToField)
import Database.SQLite.Simple.FromField (FromField)
2021-10-25 19:04:24 +03:00
newtype RedditId = RedditId Text
deriving stock (Show, Eq)
2021-10-27 23:21:09 +03:00
deriving (ToJSON, FromJSON, ToField, FromField) via Text
2021-10-25 19:04:24 +03:00
2021-10-27 23:30:48 +03:00
messages :: Session -> SubReddit -> Producer Value IO ()
2021-10-25 19:04:24 +03:00
messages sess sre = P.unfoldr go Nothing >-> P.concat
where
2021-10-27 23:30:48 +03:00
go :: Maybe Text -> IO (Either () ([Value], Maybe Text))
2021-10-25 19:04:24 +03:00
go after = do
2021-10-27 23:30:48 +03:00
let opts = defaults & header "User-Agent" .~ ["reddit-pubsub"] & param "after" .~ maybeToList after
2021-10-25 19:04:24 +03:00
r <- getWith opts sess ("https://www.reddit.com/r/" <> getSubReddit sre <> ".json")
2021-10-27 23:30:48 +03:00
let msgs = r ^.. responseBody . key "data" . key "children" . _Array . traversed . key "data"
2021-10-25 19:04:24 +03:00
next = r ^? responseBody . key "data" . key "after" . _String
print next
pure $ Right (msgs, next)
2021-10-27 23:30:48 +03:00
publishEntries :: Publish IO Value -> Session -> Fetcher -> IO ()
2021-10-25 19:04:24 +03:00
publishEntries publisher sess fetcher =
runEffect $
for
(messages sess (fetcher ^. subreddit) >-> P.take (fromIntegral $ fetcher ^. entries))
(liftIO . publish publisher)