| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- module LinkedIn.ArtDecoCard where
- import Prelude
- import Control.Monad.Maybe.Trans (MaybeT)
- import Data.Either (Either(..), hush)
- import Data.Generic.Rep (class Generic)
- import Data.List.NonEmpty (NonEmptyList)
- import Data.List.NonEmpty as NEL
- import Data.List.Types (List, NonEmptyList)
- import Data.Maybe (Maybe(..), fromJust)
- import Data.Show.Generic (genericShow)
- import Data.Traversable (sequence, traverse)
- import Debug (trace)
- import Effect (Effect)
- import Effect.Exception (try)
- import LinkedIn (DetachedNode, toDetached)
- import Partial.Unsafe (unsafePartial)
- import Web.DOM (Node, ParentNode)
- import Web.DOM.Element as E
- import Web.DOM.NodeList as NL
- import Web.DOM.ParentNode (QuerySelector(..), querySelector, querySelectorAll)
- type Parser a = Node → Effect (Either String a)
- data ArtDecoPvsEntitySubComponent = ArtDecoPvsEntitySubComponent DetachedNode
- derive instance Generic ArtDecoPvsEntitySubComponent _
- instance Show ArtDecoPvsEntitySubComponent where
- show = genericShow
- parseArtDecoPvsEntitySubComponent ∷ Parser ArtDecoPvsEntitySubComponent
- parseArtDecoPvsEntitySubComponent n = do
- content <- queryAndDetachOne "span[aria-hidden=true]" n
- pure $ ado
- c <- content
- in ArtDecoPvsEntitySubComponent c
- data ArtDecoCenterContent = ArtDecoCenterContent (NonEmptyList ArtDecoPvsEntitySubComponent)
- derive instance Generic ArtDecoCenterContent _
- instance Show ArtDecoCenterContent where
- show = genericShow
- parseArtDecoCenterContent ∷ Parser ArtDecoCenterContent
- parseArtDecoCenterContent n = do
- list <- queryManyAndParse ":scope > ul > li" parseArtDecoPvsEntitySubComponent n
- pure $ ado
- l <- list
- in ArtDecoCenterContent l
- data ArtDecoCenterHeader = ArtDecoCenterHeader {
- bold :: DetachedNode,
- normal :: Maybe DetachedNode,
- light :: Maybe (NonEmptyList DetachedNode)
- }
- derive instance Generic ArtDecoCenterHeader _
- instance Show ArtDecoCenterHeader where
- show = genericShow
- parseArtDecoCenterHeader :: Parser ArtDecoCenterHeader
- parseArtDecoCenterHeader n = do
- bold <- queryAndDetachOne ":scope div.t-bold > span[aria-hidden=true]" n
- normal <- queryAndDetachOne ":scope span.t-normal:not(t-black--light) > span[aria-hidden=true]" n
- light <- queryAndDetachMany ":scope span.t-black--light > span[aria-hidden=true]" n
- pure $ ado
- b <- bold
- in ArtDecoCenterHeader {bold: b, normal: hush normal, light: hush light}
- data ArtDecoCenter = ArtDecoCenter {
- header :: ArtDecoCenterHeader,
- content :: ArtDecoCenterContent
- }
- derive instance Generic ArtDecoCenter _
- instance Show ArtDecoCenter where
- show = genericShow
- parseArtDecoCenter :: Parser ArtDecoCenter
- parseArtDecoCenter n = do
- header <- queryOneAndParse ":scope > div" parseArtDecoCenterHeader n
- content <- queryOneAndParse ":scope > div ~ div" parseArtDecoCenterContent n
- pure $ ado
- h <- header
- c <- content
- in ArtDecoCenter {header: h, content: c}
- data ArtDecoPvsEntity = ArtDecoPvsEntity {
- side :: Unit,
- center :: ArtDecoCenter
- }
- derive instance Generic ArtDecoPvsEntity _
- instance Show ArtDecoPvsEntity where
- show = genericShow
- parseArtDecoPvsEntity :: Parser ArtDecoPvsEntity
- parseArtDecoPvsEntity n = do
- center <- queryOneAndParse ":scope > div.display-flex" parseArtDecoCenter n
- pure $ ado
- c <- center
- in ArtDecoPvsEntity {side: unit, center: c}
- data ArtDecoCardElement = ArtDecoCardElement {
- pvs_entity :: ArtDecoPvsEntity
- }
- derive instance Generic ArtDecoCardElement _
- instance Show ArtDecoCardElement where
- show = genericShow
- parseArtDecoCard :: Parser ArtDecoCardElement
- parseArtDecoCard n = do
- pvs <- queryOneAndParse ":scope div.pvs-entity--padded" parseArtDecoPvsEntity n
- pure $ ado
- p <- pvs
- in ArtDecoCardElement {pvs_entity: p}
- toParentNode' :: Node -> ParentNode
- toParentNode' n =
- unsafePartial $ fromJust $ intoParentNode' n where
- intoParentNode' :: Node -> Maybe ParentNode
- intoParentNode' node = do
- he <- E.fromNode node
- pure $ E.toParentNode he
- queryOne :: String -> Node -> Effect (Maybe Node)
- queryOne selector n = do
- found <- querySelector (QuerySelector selector) $ toParentNode' n
- pure case found of
- Nothing -> Nothing
- Just el -> Just $ E.toNode el
- queryAll :: String -> Node -> Effect (Maybe (NonEmptyList Node))
- queryAll selector n = do
- found <- querySelectorAll (QuerySelector selector) $ toParentNode' n
- liftA1 NEL.fromFoldable $ NL.toArray found
- queryAndDetachOne ∷ String -> Parser DetachedNode
- queryAndDetachOne selector n = do
- node <- queryOne selector n
- case node of
- Nothing -> pure $ Left $ "Could not find node with selector " <> selector
- Just node -> do
- node <- toDetached node
- pure $ Right node
- queryAndDetachMany ∷ String -> Parser (NonEmptyList DetachedNode)
- queryAndDetachMany selector n = do
- nodes <- queryAll selector n
- case nodes of
- Nothing -> pure $ Left $ "Did not find any node with selector " <> selector
- Just nodes -> do
- nodes <- traverse toDetached nodes
- pure $ Right nodes
- queryOneAndParse ∷ ∀ a. String → Parser a → Parser a
- queryOneAndParse selector parser n = do
- node <- queryOne selector n
- case node of
- Nothing -> pure $ Left $ "Could not find node with selector " <> selector
- Just node -> parser node
- queryManyAndParse ∷ ∀ a. String → Parser a → Parser (NonEmptyList a)
- queryManyAndParse selector parser n = do
- nodes <- queryAll selector n
- case nodes of
- Nothing -> pure $ Left $ "Did not find any node with selector " <> selector
- Just nodes -> do
- nodes <- sequence $ map parser nodes :: Effect (NonEmptyList((Either String a)))
- pure $ sequence nodes
|