LinkedIn.purs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. module LinkedIn (run, runToDetached, getContext) where
  2. import Prelude
  3. import Data.Either (Either(..))
  4. import Data.Maybe (Maybe(..))
  5. import Data.Traversable (class Traversable, traverse)
  6. import Effect (Effect)
  7. import LinkedIn.DetachedNode (DetachedNode, toDetached)
  8. import LinkedIn.Extractible (class Extractible)
  9. import LinkedIn.Extractible as LE
  10. import LinkedIn.PageUrl (PageUrl, pageUrlP)
  11. import LinkedIn.QueryRunner (QueryError, QueryRunner', runQuery)
  12. import LinkedIn.UI.Elements.Parser (fromDetachedToUI)
  13. import LinkedIn.UI.Elements.Types (UIElement)
  14. import Parsing (runParser)
  15. import Type.Proxy (Proxy)
  16. import Web.DOM (Document, Node)
  17. import Web.DOM.Document (url)
  18. import Web.URL as U
  19. getContext ∷ Document → Effect (Either String PageUrl)
  20. getContext dom = do
  21. u <- url dom
  22. pure $ case U.fromAbsolute u of
  23. Nothing -> Left "No URL found"
  24. Just u' -> case runParser (U.pathname u') pageUrlP of
  25. Left _ -> Left "Unexpected URL"
  26. Right page -> Right page
  27. run :: forall a t.
  28. Traversable t
  29. => Extractible t a
  30. => Proxy t
  31. -> Document
  32. -> Effect (Either String a)
  33. run prox dom = do
  34. detached <- runToDetached prox dom
  35. pure $ extract LE.extract $ toUI detached
  36. runToDetached :: forall t a.
  37. Traversable t
  38. => Extractible t a
  39. => Proxy t
  40. -> Document
  41. -> Effect (Either QueryError (t DetachedNode))
  42. runToDetached _ dom = do
  43. qRes <- doQuery LE.query dom
  44. detach qRes
  45. doQuery ∷ ∀ b. QueryRunner' Document b → Document → Effect (Either QueryError b)
  46. doQuery query dom = runQuery $ query dom
  47. detach ∷ ∀ a t. Traversable t ⇒ Either a (t Node) → Effect (Either a (t DetachedNode))
  48. detach = case _ of
  49. Left l -> pure $ Left l
  50. Right q -> do
  51. d <- traverse toDetached q
  52. pure $ Right d
  53. toUI ∷ ∀ a t. Traversable t ⇒ Either a (t DetachedNode) → Either String (t UIElement)
  54. toUI = case _ of
  55. Left _ -> Left "could not convert to UI"
  56. Right d -> fromDetachedToUI d
  57. extract ∷ ∀ t a. (t UIElement → Either String a) → Either String (t UIElement) → Either String a
  58. extract parsePage = case _ of
  59. Left l -> Left l
  60. Right ui -> parsePage ui