Implement the 'search' querystring

parent 723a641f
...@@ -20,9 +20,18 @@ import Protolude ...@@ -20,9 +20,18 @@ import Protolude
import qualified OpenAlex as OA import qualified OpenAlex as OA
import qualified OpenAlex.Types as OA import qualified OpenAlex.Types as OA
data Options = Options
{ filter :: Maybe OA.Filter
, search :: Maybe OA.Search }
main :: IO () main :: IO ()
main = do main = do
let filterHelp = help "Filter, for example: display_name.search:einstein , see https://docs.openalex.org/how-to-use-the-api/get-lists-of-entities/filter-entity-lists" let filterHelp = help "Filter, for example: display_name.search:einstein , see https://docs.openalex.org/how-to-use-the-api/get-lists-of-entities/filter-entity-lists"
let commonOptions =
Options <$>
optional (strOption (long "filter")) <*>
optional (strOption (long "search"))
(opts, runCmd) <- (opts, runCmd) <-
simpleOptions "0.1.0.0" simpleOptions "0.1.0.0"
"OpenAlex" "OpenAlex"
...@@ -31,38 +40,38 @@ main = do ...@@ -31,38 +40,38 @@ main = do
addCommand "concepts" addCommand "concepts"
"Fetch OpenAlex concepts (https://docs.openalex.org/api-entities/concepts/concept-object)" "Fetch OpenAlex concepts (https://docs.openalex.org/api-entities/concepts/concept-object)"
fetchConcepts fetchConcepts
(strOption (long "filter")) commonOptions
addCommand "works" addCommand "works"
"Fetch OpenAlex works (https://docs.openalex.org/api-entities/works/work-object)" "Fetch OpenAlex works (https://docs.openalex.org/api-entities/works/work-object)"
fetchWorks fetchWorks
(strOption (long "filter")) commonOptions
addCommand "works-c" addCommand "works-c"
"Fetch OpenAlex works (https://docs.openalex.org/api-entities/works/work-object) with conduit" "Fetch OpenAlex works (https://docs.openalex.org/api-entities/works/work-object) with conduit"
fetchWorksC fetchWorksC
(strOption (long "filter")) commonOptions
runCmd () runCmd ()
fetchConcepts :: OA.Filter -> () -> IO () fetchConcepts :: Options -> () -> IO ()
fetchConcepts fltr _ = do fetchConcepts Options { .. } _ = do
ec <- OA.fetchConcepts (Just 1) (Just 1) (Just "*") (Just fltr) ec <- OA.fetchConcepts (Just 1) (Just 1) (Just "*") filter search
case ec of case ec of
Left err -> putText $ "error: " <> show err Left err -> putText $ "error: " <> show err
Right c -> do Right c -> do
putText $ show c putText $ show c
fetchWorks :: OA.Filter -> () -> IO () fetchWorks :: Options -> () -> IO ()
fetchWorks fltr _ = do fetchWorks Options { .. } _ = do
ew <- OA.fetchWorks (Just 1) (Just 1) (Just "*") (Just fltr) ew <- OA.fetchWorks (Just 1) (Just 1) (Just "*") filter search
case ew of case ew of
Left err -> putText $ "error: " <> show err Left err -> putText $ "error: " <> show err
Right w -> do Right w -> do
putText $ show w putText $ show w
fetchWorksC :: OA.Filter -> () -> IO () fetchWorksC :: Options -> () -> IO ()
fetchWorksC fltr _ = do fetchWorksC Options { .. } _ = do
eWorksC <- OA.fetchWorksC Nothing (Just fltr) eWorksC <- OA.fetchWorksC Nothing filter search
case eWorksC of case eWorksC of
Left err -> putText $ "error: " <> show err Left err -> putText $ "error: " <> show err
Right (mCount, c) -> do Right (mCount, c) -> do
...@@ -71,6 +80,6 @@ fetchWorksC fltr _ = do ...@@ -71,6 +80,6 @@ fetchWorksC fltr _ = do
.| takeC 3 .| takeC 3
.| mapM_C (\w@(OA.Work { .. }) -> do .| mapM_C (\w@(OA.Work { .. }) -> do
liftIO $ putText $ show id <> " :: " <> show display_name liftIO $ putText $ show id <> " :: " <> show display_name
liftIO $ putText abstract_reconstructed -- liftIO $ putText abstract_reconstructed
) )
pure () pure ()
...@@ -27,7 +27,7 @@ import Network.HTTP.Client.TLS (tlsManagerSettings) ...@@ -27,7 +27,7 @@ import Network.HTTP.Client.TLS (tlsManagerSettings)
import Protolude hiding (yield) import Protolude hiding (yield)
import OpenAlex.Client import OpenAlex.Client
import OpenAlex.ServantClientLogging import OpenAlex.ServantClientLogging
import OpenAlex.Types (ListOf(..), Meta(..), Page, PerPage, Cursor, Filter, Concept, Work) import OpenAlex.Types (ListOf(..), Meta(..), Page, PerPage, Cursor, Filter, Search, Concept, Work)
import Servant.Client (BaseUrl(..), ClientEnv(..), ClientError, Scheme(Https), defaultMakeClientRequest, mkClientEnv, runClientM) import Servant.Client (BaseUrl(..), ClientEnv(..), ClientError, Scheme(Https), defaultMakeClientRequest, mkClientEnv, runClientM)
defaultClientEnv :: IO ClientEnv defaultClientEnv :: IO ClientEnv
...@@ -45,29 +45,32 @@ fetchConcepts :: Maybe Page ...@@ -45,29 +45,32 @@ fetchConcepts :: Maybe Page
-> Maybe PerPage -> Maybe PerPage
-> Maybe Cursor -> Maybe Cursor
-> Maybe Filter -> Maybe Filter
-> Maybe Search
-> IO (Either ClientError (ListOf Concept)) -> IO (Either ClientError (ListOf Concept))
fetchConcepts mPage mPerPage mCursor mFilter = do fetchConcepts mPage mPerPage mCursor mFilter mSearch = do
env <- defaultClientEnv env <- defaultClientEnv
runClientM (concepts mPage mPerPage mCursor mFilter) env runClientM (concepts mPage mPerPage mCursor mFilter mSearch) env
fetchWorks :: Maybe Page fetchWorks :: Maybe Page
-> Maybe PerPage -> Maybe PerPage
-> Maybe Cursor -> Maybe Cursor
-> Maybe Filter -> Maybe Filter
-> Maybe Search
-> IO (Either ClientError (ListOf Work)) -> IO (Either ClientError (ListOf Work))
fetchWorks mPage mPerPage mCursor mFilter = do fetchWorks mPage mPerPage mCursor mFilter mSearch = do
env <- defaultClientEnv env <- defaultClientEnv
runClientM (works mPage mPerPage mCursor mFilter) env runClientM (works mPage mPerPage mCursor mFilter mSearch) env
fetchWorksC :: Maybe Cursor fetchWorksC :: Maybe Cursor
-> Maybe Filter -> Maybe Filter
-> Maybe Search
-> IO (Either ClientError (Maybe Integer, ConduitT () Work IO ())) -> IO (Either ClientError (Maybe Integer, ConduitT () Work IO ()))
fetchWorksC Nothing mFilter = do fetchWorksC Nothing mFilter mSearch = do
fetchWorksC (Just "*") mFilter fetchWorksC (Just "*") mFilter mSearch
fetchWorksC mCursor mFilter = do fetchWorksC mCursor mFilter mSearch = do
env <- defaultClientEnv env <- defaultClientEnv
-- NOTE: per-page max is 200 -- NOTE: per-page max is 200
eRes <- runClientM (works (Just 1) (Just 1) Nothing mFilter) env eRes <- runClientM (works (Just 1) (Just 1) Nothing mFilter mSearch) env
case eRes of case eRes of
Left err -> pure $ Left err Left err -> pure $ Left err
Right ListOf { meta = Meta { count }} -> do Right ListOf { meta = Meta { count }} -> do
...@@ -76,7 +79,7 @@ fetchWorksC mCursor mFilter = do ...@@ -76,7 +79,7 @@ fetchWorksC mCursor mFilter = do
where where
producer :: ClientEnv -> Maybe Cursor -> ConduitT () Work IO () producer :: ClientEnv -> Maybe Cursor -> ConduitT () Work IO ()
producer env mCursor' = do producer env mCursor' = do
eRes <- liftIO $ runClientM (works Nothing (Just 200) mCursor' mFilter) env eRes <- liftIO $ runClientM (works Nothing (Just 200) mCursor' mFilter mSearch) env
-- liftIO $ putText $ "Conduit fetching page with cursor " <> show mCursor' -- liftIO $ putText $ "Conduit fetching page with cursor " <> show mCursor'
case eRes of case eRes of
Left err -> panic $ "error: " <> show err Left err -> panic $ "error: " <> show err
......
...@@ -16,7 +16,7 @@ import Protolude ...@@ -16,7 +16,7 @@ import Protolude
import Servant.API import Servant.API
import Servant.Client import Servant.Client
import OpenAlex.Types (Page, PerPage, Cursor, Filter, ListOf(..), Concept, Work) import OpenAlex.Types (Page, PerPage, Cursor, Filter, Search, ListOf(..), Concept, Work)
type API_URL = Text type API_URL = Text
apiUrl :: API_URL apiUrl :: API_URL
...@@ -35,6 +35,7 @@ type OpenAlexAPI = ...@@ -35,6 +35,7 @@ type OpenAlexAPI =
:> QueryParam "per-page" PerPage :> QueryParam "per-page" PerPage
:> QueryParam "cursor" Cursor :> QueryParam "cursor" Cursor
:> QueryParam "filter" Filter :> QueryParam "filter" Filter
:> QueryParam "search" Search
-- TODO: filter, search, sort -- TODO: filter, search, sort
:> Get '[JSON] (ListOf Concept) :> Get '[JSON] (ListOf Concept)
...@@ -44,14 +45,25 @@ type OpenAlexAPI = ...@@ -44,14 +45,25 @@ type OpenAlexAPI =
:> QueryParam "per-page" PerPage :> QueryParam "per-page" PerPage
:> QueryParam "cursor" Cursor :> QueryParam "cursor" Cursor
:> QueryParam "filter" Filter :> QueryParam "filter" Filter
:> QueryParam "search" Search
-- TODO: filter, search, sort -- TODO: filter, search, sort
:> Get '[JSON] (ListOf Work) :> Get '[JSON] (ListOf Work)
openAlexApi :: Proxy OpenAlexAPI openAlexApi :: Proxy OpenAlexAPI
openAlexApi = Proxy openAlexApi = Proxy
concepts :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> Maybe Filter -> ClientM (ListOf Concept) concepts :: Maybe Page
-> Maybe PerPage
-> Maybe Cursor
-> Maybe Filter
-> Maybe Search
-> ClientM (ListOf Concept)
works :: Maybe Page -> Maybe PerPage -> Maybe Cursor -> Maybe Filter -> ClientM (ListOf Work) works :: Maybe Page
-> Maybe PerPage
-> Maybe Cursor
-> Maybe Filter
-> Maybe Search
-> ClientM (ListOf Work)
concepts :<|> works = client openAlexApi concepts :<|> works = client openAlexApi
...@@ -30,6 +30,7 @@ type Page = Int ...@@ -30,6 +30,7 @@ type Page = Int
type PerPage = Int type PerPage = Int
type Filter = Text type Filter = Text
type Search = Text
-- API response types -- API response types
......
{-| {-|
Module : OpenAlex Utils Module : OpenAlex Utils
Description : Textmining Collaborative Platform Description : Textmining Collaborative Platform
Copyright : (c) CNRS, 2023 Copyright : (c) CNRS, 2023-present
License : AGPL + CECILL v3 License : AGPL + CECILL v3
Maintainer : team@gargantext.org Maintainer : team@gargantext.org
Stability : experimental Stability : experimental
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment