LinkedIn.purs 2.1 KB

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