Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Proj.DevTo.Fetcher
- ( startLink
- , getPosts
- , getState
- , State
- , Message
- ) where
- import Prelude
- import Data.Array as Array
- import Data.Either (Either(..))
- import Data.Maybe (Maybe(..))
- import Data.Time.Duration (Milliseconds(..), Minutes(..))
- import Data.Time.Duration as Duration
- import Effect (Effect)
- import Effect.Class (liftEffect)
- import Erl.Atom (Atom, atom)
- import Erl.Data.List (List)
- import Logger as Logger
- import Pinto.GenServer (InfoFn, InitFn, InitResult(..), ServerPid, ServerType)
- import Pinto.GenServer as GenServer
- import Pinto.Timer as Timer
- import Pinto.Types (RegistryName(..), RegistryReference(..), StartLinkResult)
- import Proj.DevTo as DevTo
- import Proj.DevTo.Types (DevToApiKey, DevToUsername, Post)
- type State =
- { posts :: List Post
- , username :: DevToUsername
- , apiKey :: DevToApiKey
- }
- data Message = Fetch
- serverName :: RegistryName (ServerType Unit Unit Message State)
- serverName = "Proj.DevTo.Fetcher" # atom # Local
- startLink
- :: DevToApiKey
- -> DevToUsername
- -> Effect (StartLinkResult (ServerPid Unit Unit Message State))
- startLink apiKey username =
- GenServer.startLink
- $ (GenServer.defaultSpec init) { name = Just serverName, handleInfo = Just handleInfo }
- where
- init :: InitFn Unit Unit Message State
- init = do
- _ <- Timer.sendAfter (Milliseconds 0.0) Fetch
- pure $ InitOk { posts: Array.toUnfoldable [], username, apiKey }
- getPosts :: Effect (List Post)
- getPosts = GenServer.call (ByName serverName) $ \_from state ->
- pure $ GenServer.reply state.posts state
- getState :: Effect State
- getState = GenServer.call (ByName serverName) $ \_from state -> pure $ GenServer.reply state state
- handleInfo :: InfoFn Unit Unit Message State
- handleInfo Fetch state@{ apiKey, username } = do
- liftEffect $ Logger.debug { domain, type: Logger.Trace } { message: "Fetching posts from Dev.to" }
- maybePosts <- liftEffect $ DevTo.getPosts apiKey username
- case maybePosts of
- Right newPosts -> do
- _ <- Timer.sendAfter (1.0 # Minutes # Duration.fromDuration) Fetch
- pure $ GenServer.return $ state { posts = newPosts }
- Left err -> do
- _ <- liftEffect $ Logger.error { domain, type: Logger.Trace } { error: err }
- _ <- Timer.sendAfter (1.0 # Minutes # Duration.fromDuration) Fetch
- pure $ GenServer.return state
- domain :: List Atom
- domain = Array.toUnfoldable [ atom "Proj.DevTo.Fetcher" ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement