Migrate to flake, fix openalex exe params

parent c86412b5
use_nix use_flake
export LANG=C.UTF-8 export LANG=C.UTF-8
...@@ -20,14 +20,19 @@ import Data.Conduit.Combinators qualified as Conduit ...@@ -20,14 +20,19 @@ import Data.Conduit.Combinators qualified as Conduit
import Data.Conduit.List qualified as CL import Data.Conduit.List qualified as CL
import Data.Csv qualified as Csv import Data.Csv qualified as Csv
import Data.Csv.Conduit qualified as CsvC import Data.Csv.Conduit qualified as CsvC
import Data.Text qualified as T
import OpenAlex qualified as OA import OpenAlex qualified as OA
import OpenAlex.Types qualified as OA import OpenAlex.Types qualified as OA
import Options.Applicative.Simple import Options.Applicative.Simple
import Prelude qualified
import Protolude import Protolude
import Text.Layout.Table as TLT
data Options = Options data Options = Options
{ filter :: Maybe OA.Filter { page :: Int
, search :: Maybe OA.Search } , perPage :: Int
, filter :: Maybe OA.Filter
, search :: Maybe OA.Search }
data ToCSVOptions = ToCSVOptions data ToCSVOptions = ToCSVOptions
{ options :: Options { options :: Options
...@@ -38,6 +43,8 @@ main = do ...@@ -38,6 +43,8 @@ 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 = let commonOptions =
Options <$> Options <$>
option auto (long "page" <> value 1 <> showDefault) <*>
option auto (long "per-page" <> value 20 <> showDefault) <*>
optional (strOption (long "filter")) <*> optional (strOption (long "filter")) <*>
optional (strOption (long "search")) optional (strOption (long "search"))
...@@ -81,11 +88,12 @@ fetchConcepts Options { .. } _ = do ...@@ -81,11 +88,12 @@ fetchConcepts Options { .. } _ = do
fetchWorks :: Options -> () -> IO () fetchWorks :: Options -> () -> IO ()
fetchWorks Options { .. } _ = do fetchWorks Options { .. } _ = do
ew <- OA.fetchWorks (Just 1) (Just 1) (Just "*") filter search ew <- OA.fetchWorks (Just page) (Just perPage) (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 (OA.ListOf { meta = OA.Meta { count }, results }) -> do
putText $ show w putText $ "Count: " <> show count
prettyPrintWorks results
fetchWorksC :: Options -> () -> IO () fetchWorksC :: Options -> () -> IO ()
fetchWorksC Options { .. } _ = do fetchWorksC Options { .. } _ = do
...@@ -98,7 +106,7 @@ fetchWorksC Options { .. } _ = do ...@@ -98,7 +106,7 @@ fetchWorksC Options { .. } _ = do
.| takeC 3 .| takeC 3
.| mapM_C (\w@(OA.Work { .. }) -> do .| mapM_C (\w@(OA.Work { .. }) -> do
liftIO $ do liftIO $ do
putText $ show id <> " :: " <> show display_name putText $ show doi <> " :: " <> show title <> " :: " <> show url
putText abstract_reconstructed putText abstract_reconstructed
putText "-----" putText "-----"
) )
...@@ -125,3 +133,22 @@ toNamedCsv :: (Monad m, Csv.DefaultOrdered a, Csv.ToNamedRecord a) ...@@ -125,3 +133,22 @@ toNamedCsv :: (Monad m, Csv.DefaultOrdered a, Csv.ToNamedRecord a)
=> Csv.EncodeOptions => Csv.EncodeOptions
-> ConduitT a BS.ByteString m () -> ConduitT a BS.ByteString m ()
toNamedCsv opts = {-# SCC toCsv_p #-} CL.map $ BSL.toStrict . Csv.encodeDefaultOrderedByNameWith opts . pure toNamedCsv opts = {-# SCC toCsv_p #-} CL.map $ BSL.toStrict . Csv.encodeDefaultOrderedByNameWith opts . pure
prettyPrintWorks :: [OA.Work] -> IO ()
prettyPrintWorks works = do
let emptyS = "---"
-- let trim_ num = TLT.trim TLT.left TLT.ellipsisCutMark num
let cs = [
def
, TLT.column (TLT.fixed 40) TLT.left TLT.noAlign TLT.ellipsisCutMark
, def
, TLT.column (TLT.fixed 40) TLT.left TLT.noAlign TLT.ellipsisCutMark ]
let h = TLT.titlesH ([ "DOI", "Title", "URL", "Abstract" ] :: [Prelude.String])
let rgs = (\(OA.Work { .. }) -> TLT.rowG [ fromMaybe emptyS doi
, fromMaybe emptyS title
, fromMaybe emptyS url
, abstract_reconstructed ]) <$> works
let t = TLT.columnHeaderTableS cs TLT.unicodeS h rgs
putText $ T.pack $ TLT.tableString t
index-state: 2025-04-17T20:37:02Z
with-compiler: ghc-9.6.6
optimization: 2
benchmarks: False
tests: True
packages:
./
This diff is collapsed.
{
description = "OpenAlex client";
inputs = {
flake-utils.url = "github:numtide/flake-utils";
haskell-nix = {
url = "github:input-output-hk/haskell.nix";
};
nixpkgs.follows = "haskell-nix/nixpkgs-unstable";
};
outputs = { self, nixpkgs, flake-utils, haskell-nix }:
flake-utils.lib.eachDefaultSystem (system:
let
compiler-nix-name = "ghc96";
pkgs = import nixpkgs {
inherit system;
config = haskell-nix.config;
overlays = [
haskell-nix.overlay
(final: prev: {
# This overlay adds our project to the package set
openalex-hs =
final.haskell-nix.project' {
inherit compiler-nix-name;
src = ./.;
};
})
];
};
flake = pkgs.openalex-hs.flake {};
in
{
# Built by `nix build`
packages = flake.packages // {
default = flake.packages."openalex:lib:openalex";
};
# Run by `nix run`
apps = flake.apps;
# Used by `nix develop`
devShells = flake.devShells // {
default = flake.devShells.default.overrideAttrs (oldAttrs: rec {
buildInputs = oldAttrs.buildInputs ++ [
# Add additional development tools here
pkgs.cabal-install
pkgs.hlint
pkgs.haskell-language-server
];
});
};
# Used by `nix flake check`
checks = flake.checks;
});
# Add the nixConfig section for binary caches
nixConfig = {
extra-substituters = [
"https://cache.iog.io"
];
extra-trusted-public-keys = [
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
allow-import-from-derivation = true;
};
}
import (builtins.fetchGit {
name = "nixos-22.05";
url = "https://github.com/nixos/nixpkgs";
ref = "refs/heads/nixos-22.05";
rev = "ce6aa13369b667ac2542593170993504932eb836";
})
import (builtins.fetchGit {
name = "nixos-23.11";
url = "https://github.com/nixos/nixpkgs";
ref = "refs/heads/nixos-23.11";
rev = "057f9aecfb71c4437d2b27d3323df7f93c010b7e";
})
{ pkgs ? import ./pinned-23.11.nix {} }:
rec {
inherit pkgs;
ghc = pkgs.haskell.compiler.ghc947;
hsBuildInputs = [
ghc
pkgs.cabal-install
];
pythonEnv = pkgs.python3.withPackages(ps: [
ps.ipywidgets
ps.pandas
ps.tqdm
]);
nonhsBuildInputs = with pkgs; [
gmp
jupyter
pythonEnv
zlib
];
#libPaths = pkgs.lib.makeLibraryPath nonhsBuildInputs;
shell = pkgs.mkShell {
name = "openalex";
buildInputs = nonhsBuildInputs;
};
}
cabal-version: 2.4 cabal-version: 3.4
name: openalex name: openalex
version: 0.2.0.0 version: 0.2.0.0
...@@ -82,7 +82,7 @@ library ...@@ -82,7 +82,7 @@ library
, time >= 1.9.3 && < 1.13 , time >= 1.9.3 && < 1.13
, vector >= 0.12.3 && < 0.14 , vector >= 0.12.3 && < 0.14
executable openalex-main executable openalex
import: import:
defaults defaults
main-is: Main.hs main-is: Main.hs
...@@ -95,6 +95,8 @@ executable openalex-main ...@@ -95,6 +95,8 @@ executable openalex-main
build-depends: build-depends:
cassava-conduit >= 0.6.5 && < 0.7 cassava-conduit >= 0.6.5 && < 0.7
, optparse-simple >= 0.1.1.4 && < 0.2 , optparse-simple >= 0.1.1.4 && < 0.2
, table-layout >= 1.0 && < 2
, text >= 2.0 && < 3
, openalex , openalex
hs-source-dirs: app hs-source-dirs: app
......
{ pkgs ? import ./nix/pkgs.nix {} }:
let
in
pkgs.pkgs.mkShell {
name = pkgs.shell.name;
shellHook = pkgs.shell.shellHook;
buildInputs = pkgs.shell.buildInputs;
}
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