Advertisement
Guest User

Untitled

a guest
Jan 1st, 2023
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Proj.DevTo.Fetcher
  2.   ( startLink
  3.   , getPosts
  4.   , getState
  5.   , State
  6.   , Message
  7.   ) where
  8.  
  9. import Prelude
  10.  
  11. import Data.Array as Array
  12. import Data.Either (Either(..))
  13. import Data.Maybe (Maybe(..))
  14. import Data.Time.Duration (Milliseconds(..), Minutes(..))
  15. import Data.Time.Duration as Duration
  16. import Effect (Effect)
  17. import Effect.Class (liftEffect)
  18. import Erl.Atom (Atom, atom)
  19. import Erl.Data.List (List)
  20. import Logger as Logger
  21. import Pinto.GenServer (InfoFn, InitFn, InitResult(..), ServerPid, ServerType)
  22. import Pinto.GenServer as GenServer
  23. import Pinto.Timer as Timer
  24. import Pinto.Types (RegistryName(..), RegistryReference(..), StartLinkResult)
  25. import Proj.DevTo as DevTo
  26. import Proj.DevTo.Types (DevToApiKey, DevToUsername, Post)
  27.  
  28. type State =
  29.   { posts :: List Post
  30.   , username :: DevToUsername
  31.   , apiKey :: DevToApiKey
  32.   }
  33.  
  34. data Message = Fetch
  35.  
  36. serverName :: RegistryName (ServerType Unit Unit Message State)
  37. serverName = "Proj.DevTo.Fetcher" # atom # Local
  38.  
  39. startLink
  40.   :: DevToApiKey
  41.   -> DevToUsername
  42.   -> Effect (StartLinkResult (ServerPid Unit Unit Message State))
  43. startLink apiKey username =
  44.   GenServer.startLink
  45.     $ (GenServer.defaultSpec init) { name = Just serverName, handleInfo = Just handleInfo }
  46.   where
  47.   init :: InitFn Unit Unit Message State
  48.   init = do
  49.     _ <- Timer.sendAfter (Milliseconds 0.0) Fetch
  50.     pure $ InitOk { posts: Array.toUnfoldable [], username, apiKey }
  51.  
  52. getPosts :: Effect (List Post)
  53. getPosts = GenServer.call (ByName serverName) $ \_from state ->
  54.   pure $ GenServer.reply state.posts state
  55.  
  56. getState :: Effect State
  57. getState = GenServer.call (ByName serverName) $ \_from state -> pure $ GenServer.reply state state
  58.  
  59. handleInfo :: InfoFn Unit Unit Message State
  60. handleInfo Fetch state@{ apiKey, username } = do
  61.   liftEffect $ Logger.debug { domain, type: Logger.Trace } { message: "Fetching posts from Dev.to" }
  62.   maybePosts <- liftEffect $ DevTo.getPosts apiKey username
  63.   case maybePosts of
  64.     Right newPosts -> do
  65.       _ <- Timer.sendAfter (1.0 # Minutes # Duration.fromDuration) Fetch
  66.       pure $ GenServer.return $ state { posts = newPosts }
  67.     Left err -> do
  68.       _ <- liftEffect $ Logger.error { domain, type: Logger.Trace } { error: err }
  69.       _ <- Timer.sendAfter (1.0 # Minutes # Duration.fromDuration) Fetch
  70.       pure $ GenServer.return state
  71.  
  72. domain :: List Atom
  73. domain = Array.toUnfoldable [ atom "Proj.DevTo.Fetcher" ]
  74.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement