{-# LANGUAGE OverloadedStrings #-}
module Poseidon.CLI.List (runList, ListOptions(..), ListEntity(..), RepoLocationSpec(..)) where
import Poseidon.BibFile (authorAbbrvString, parseAuthors)
import Poseidon.Contributor (ContributorSpec (..), renderORCID)
import Poseidon.EntityTypes (HasNameAndVersion (..))
import Poseidon.Package (PackageReadOptions (..),
defaultPackageReadOptions,
getAllGroupInfo, getBibliographyInfo,
getExtendedIndividualInfo,
packagesToPackageInfos,
readPoseidonPackageCollection)
import Poseidon.ServerClient (AddColSpec (..), ApiReturnData (..),
ArchiveEndpoint (..),
BibliographyInfo (..),
ExtendedIndividualInfo (..),
GroupInfo (..), PackageInfo (..),
processApiResponse, qDefault)
import Poseidon.Utils (PoseidonIO, logInfo, logWarning)
import Control.Monad (forM_, when)
import Control.Monad.IO.Class (liftIO)
import Data.List (intercalate, nub, sortOn)
import Data.Maybe (catMaybes, fromMaybe)
import qualified Data.Text as T
import Data.Version (Version, showVersion)
import Text.Layout.Table (asciiRoundS, column, def, expandUntil,
rowsG, tableString, titlesH)
data ListOptions = ListOptions
{ ListOptions -> RepoLocationSpec
_listRepoLocation :: RepoLocationSpec
, ListOptions -> ListEntity
_listListEntity :: ListEntity
, ListOptions -> Bool
_listRawOutput :: Bool
, ListOptions -> Bool
_listOnlyLatest :: Bool
}
data RepoLocationSpec = RepoLocal [FilePath] | RepoRemote ArchiveEndpoint
data ListEntity = ListPackages Bool
| ListGroups
| ListIndividuals AddColSpec
| ListBibliography AddColSpec
runList :: ListOptions -> PoseidonIO ()
runList :: ListOptions -> PoseidonIO ()
runList (ListOptions RepoLocationSpec
repoLocation ListEntity
listEntity Bool
rawOutput Bool
onlyLatest) = do
let pacReadOpts :: PackageReadOptions
pacReadOpts = PackageReadOptions
defaultPackageReadOptions {
_readOptIgnoreChecksums = True
, _readOptGenoCheck = False
, _readOptIgnoreGeno = True
, _readOptOnlyLatest = onlyLatest
}
([[Char]]
tableH, [[[Char]]]
tableB) <- case ListEntity
listEntity of
ListPackages Bool
fullOutput -> do
[PackageInfo]
packageInfos <- case RepoLocationSpec
repoLocation of
RepoRemote (ArchiveEndpoint [Char]
remoteURL Maybe [Char]
archive) -> do
[Char] -> PoseidonIO ()
logInfo [Char]
"Downloading package data from server"
ApiReturnData
apiReturn <- [Char] -> Bool -> PoseidonIO ApiReturnData
processApiResponse ([Char]
remoteURL [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/packages" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
qDefault Maybe [Char]
archive) Bool
False
case ApiReturnData
apiReturn of
ApiReturnPackageInfo [PackageInfo]
pacInfo -> [PackageInfo] -> ReaderT Env IO [PackageInfo]
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [PackageInfo]
pacInfo
ApiReturnData
_ -> [Char] -> ReaderT Env IO [PackageInfo]
forall a. HasCallStack => [Char] -> a
error [Char]
"should not happen"
RepoLocal [[Char]]
baseDirs -> do
[PoseidonPackage]
pacCollection <- PackageReadOptions -> [[Char]] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection PackageReadOptions
pacReadOpts [[Char]]
baseDirs
Bool -> [PoseidonPackage] -> ReaderT Env IO [PackageInfo]
forall (m :: * -> *).
MonadThrow m =>
Bool -> [PoseidonPackage] -> m [PackageInfo]
packagesToPackageInfos Bool
True [PoseidonPackage]
pacCollection
let tableH :: [[Char]]
tableH =
let baseColumnH :: [[Char]]
baseColumnH = [[Char]
"Package", [Char]
"Package Version", [Char]
"Is Latest", [Char]
"Poseidon Version", [Char]
"Description", [Char]
"Last modified", [Char]
"Nr Individuals"]
in if Bool
fullOutput then
[[Char]]
baseColumnH [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]
"Contributors", [Char]
"Base Directory", [Char]
"GenotypeFiles", [Char]
"JannoFile", [Char]
"SeqSourceFile", [Char]
"BibFile", [Char]
"ReadmeFile", [Char]
"ChangelogFile"]
else
[[Char]]
baseColumnH
tableB :: [[[Char]]]
tableB = ([[Char]] -> [Char]) -> [[[Char]]] -> [[[Char]]]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn [[Char]] -> [Char]
forall a. HasCallStack => [a] -> a
head ([[[Char]]] -> [[[Char]]]) -> [[[Char]]] -> [[[Char]]]
forall a b. (a -> b) -> a -> b
$ do
PackageInfo
pInf <- [PackageInfo]
packageInfos
Bool
True <- Bool -> [Bool]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Bool
not Bool
onlyLatest Bool -> Bool -> Bool
|| PackageInfo -> Bool
pIsLatest PackageInfo
pInf)
let baseCols :: [[Char]]
baseCols = [PackageInfo -> [Char]
forall a. HasNameAndVersion a => a -> [Char]
getPacName PackageInfo
pInf, Maybe Version -> [Char]
showMaybeVersion (PackageInfo -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PackageInfo
pInf), Bool -> [Char]
forall a. Show a => a -> [Char]
show (Bool -> [Char]) -> Bool -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Bool
pIsLatest PackageInfo
pInf,
Version -> [Char]
showVersion (Version -> [Char]) -> Version -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Version
pPosVersion PackageInfo
pInf, Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pDescription PackageInfo
pInf, Maybe [Char] -> [Char]
showMaybe (Day -> [Char]
forall a. Show a => a -> [Char]
show (Day -> [Char]) -> Maybe Day -> Maybe [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PackageInfo -> Maybe Day
pLastModified PackageInfo
pInf), Int -> [Char]
forall a. Show a => a -> [Char]
show (Int -> [Char]) -> Int -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Int
pNrIndividuals PackageInfo
pInf]
if Bool
fullOutput then
[[Char]] -> [[[Char]]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> a -> b
$ [[Char]]
baseCols [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
";" ([[Char]] -> [Char])
-> (PackageInfo -> [[Char]]) -> PackageInfo -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContributorSpec -> [Char]) -> [ContributorSpec] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ContributorSpec -> [Char]
showContributor ([ContributorSpec] -> [[Char]])
-> (PackageInfo -> [ContributorSpec]) -> PackageInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageInfo -> [ContributorSpec]
pContributors (PackageInfo -> [Char]) -> PackageInfo -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo
pInf, Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pBaseDir PackageInfo
pInf, [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"," ([[Char]] -> [Char])
-> (PackageInfo -> [[Char]]) -> PackageInfo -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageInfo -> [[Char]]
pGenotypeFiles (PackageInfo -> [Char]) -> PackageInfo -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo
pInf,
Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pJannoFile PackageInfo
pInf, Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pSeqSourceFile PackageInfo
pInf, Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pBibFile PackageInfo
pInf, Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pReadmeFile PackageInfo
pInf,
Maybe [Char] -> [Char]
showMaybe (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ PackageInfo -> Maybe [Char]
pChangelogFile PackageInfo
pInf]
else
[[Char]] -> [[[Char]]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [[Char]]
baseCols
([[Char]], [[[Char]]]) -> ReaderT Env IO ([[Char]], [[[Char]]])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]]
tableH, [[[Char]]]
tableB)
ListEntity
ListGroups -> do
[GroupInfo]
groupInfos <- case RepoLocationSpec
repoLocation of
RepoRemote (ArchiveEndpoint [Char]
remoteURL Maybe [Char]
archive) -> do
[Char] -> PoseidonIO ()
logInfo [Char]
"Downloading group data from server"
ApiReturnData
apiReturn <- [Char] -> Bool -> PoseidonIO ApiReturnData
processApiResponse ([Char]
remoteURL [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/groups" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
qDefault Maybe [Char]
archive) Bool
False
case ApiReturnData
apiReturn of
ApiReturnGroupInfo [GroupInfo]
groupInfo -> [GroupInfo] -> ReaderT Env IO [GroupInfo]
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [GroupInfo]
groupInfo
ApiReturnData
_ -> [Char] -> ReaderT Env IO [GroupInfo]
forall a. HasCallStack => [Char] -> a
error [Char]
"should not happen"
RepoLocal [[Char]]
baseDirs -> do
[PoseidonPackage]
pacCollection <- PackageReadOptions -> [[Char]] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection PackageReadOptions
pacReadOpts [[Char]]
baseDirs
[PoseidonPackage] -> ReaderT Env IO [GroupInfo]
forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> m [GroupInfo]
getAllGroupInfo [PoseidonPackage]
pacCollection
let tableH :: [[Char]]
tableH = [[Char]
"Group", [Char]
"Package", [Char]
"Package Version", [Char]
"Is Latest", [Char]
"Nr Individuals"]
tableB :: [[[Char]]]
tableB = do
gi :: GroupInfo
gi@(GroupInfo [Char]
groupName PacNameAndVersion
_ Bool
isLatest Int
nrInds) <- [GroupInfo]
groupInfos
Bool
True <- Bool -> [Bool]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Bool
not Bool
onlyLatest Bool -> Bool -> Bool
|| Bool
isLatest)
[[Char]] -> [[[Char]]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [[Char]
groupName, GroupInfo -> [Char]
forall a. HasNameAndVersion a => a -> [Char]
getPacName GroupInfo
gi, Maybe Version -> [Char]
showMaybeVersion (GroupInfo -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion GroupInfo
gi), Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
isLatest, Int -> [Char]
forall a. Show a => a -> [Char]
show Int
nrInds]
([[Char]], [[[Char]]]) -> ReaderT Env IO ([[Char]], [[[Char]]])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]]
tableH, [[[Char]]]
tableB)
ListIndividuals AddColSpec
addJannoColSpec -> do
[ExtendedIndividualInfo]
extIndInfos <- case RepoLocationSpec
repoLocation of
RepoRemote (ArchiveEndpoint [Char]
remoteURL Maybe [Char]
archive) -> do
[Char] -> PoseidonIO ()
logInfo [Char]
"Downloading individual data from server"
let addJannoColFlag :: [Char]
addJannoColFlag = case AddColSpec
addJannoColSpec of
AddColSpec
AddColAll -> [Char]
"&additionalJannoColumns=ALL"
AddColList [] -> [Char]
""
AddColList [[Char]]
moreJannoColumns -> [Char]
"&additionalJannoColumns=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"," [[Char]]
moreJannoColumns
ApiReturnData
apiReturn <- [Char] -> Bool -> PoseidonIO ApiReturnData
processApiResponse ([Char]
remoteURL [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/individuals" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
qDefault Maybe [Char]
archive [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
addJannoColFlag) Bool
False
case ApiReturnData
apiReturn of
ApiReturnExtIndividualInfo [ExtendedIndividualInfo]
indInfo -> [ExtendedIndividualInfo] -> ReaderT Env IO [ExtendedIndividualInfo]
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [ExtendedIndividualInfo]
indInfo
ApiReturnData
_ -> [Char] -> ReaderT Env IO [ExtendedIndividualInfo]
forall a. HasCallStack => [Char] -> a
error [Char]
"should not happen"
RepoLocal [[Char]]
baseDirs -> do
[PoseidonPackage]
pacCollection <- PackageReadOptions -> [[Char]] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection PackageReadOptions
pacReadOpts [[Char]]
baseDirs
[PoseidonPackage]
-> AddColSpec -> ReaderT Env IO [ExtendedIndividualInfo]
forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> AddColSpec -> m [ExtendedIndividualInfo]
getExtendedIndividualInfo [PoseidonPackage]
pacCollection AddColSpec
addJannoColSpec
let addJannoCols :: [[Char]]
addJannoCols = case [ExtendedIndividualInfo]
extIndInfos of
[] -> []
(ExtendedIndividualInfo
e:[ExtendedIndividualInfo]
_) -> (([Char], Maybe [Char]) -> [Char])
-> [([Char], Maybe [Char])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], Maybe [Char]) -> [Char]
forall a b. (a, b) -> a
fst ([([Char], Maybe [Char])] -> [[Char]])
-> (ExtendedIndividualInfo -> [([Char], Maybe [Char])])
-> ExtendedIndividualInfo
-> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtendedIndividualInfo -> [([Char], Maybe [Char])]
extIndInfoAddCols (ExtendedIndividualInfo -> [[Char]])
-> ExtendedIndividualInfo -> [[Char]]
forall a b. (a -> b) -> a -> b
$ ExtendedIndividualInfo
e
case AddColSpec
addJannoColSpec of
AddColList ([Char]
_:[[Char]]
_) -> do
[(Int, [Char])]
-> ((Int, [Char]) -> PoseidonIO ()) -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Int] -> [[Char]] -> [(Int, [Char])]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [[Char]]
addJannoCols) (((Int, [Char]) -> PoseidonIO ()) -> PoseidonIO ())
-> ((Int, [Char]) -> PoseidonIO ()) -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ \(Int
i, [Char]
columnKey) -> do
let nonEmptyEntries :: [[Char]]
nonEmptyEntries = [Maybe [Char]] -> [[Char]]
forall a. [Maybe a] -> [a]
catMaybes [([Char], Maybe [Char]) -> Maybe [Char]
forall a b. (a, b) -> b
snd ([([Char], Maybe [Char])]
entries [([Char], Maybe [Char])] -> Int -> ([Char], Maybe [Char])
forall a. HasCallStack => [a] -> Int -> a
!! Int
i) | ExtendedIndividualInfo [Char]
_ [[Char]]
_ PacNameAndVersion
_ Bool
_ [([Char], Maybe [Char])]
entries <- [ExtendedIndividualInfo]
extIndInfos]
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([[Char]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
nonEmptyEntries) (PoseidonIO () -> PoseidonIO ())
-> ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> PoseidonIO ()
logWarning ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Column Name " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
columnKey [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" not present in any individual"
AddColSpec
_ -> () -> PoseidonIO ()
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
let tableH :: [[Char]]
tableH = [[Char]
"Individual", [Char]
"Group", [Char]
"Package", [Char]
"PackageVersion", [Char]
"Is Latest"] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]]
addJannoCols
tableB :: [[[Char]]]
tableB = do
i :: ExtendedIndividualInfo
i@(ExtendedIndividualInfo [Char]
name [[Char]]
groups PacNameAndVersion
_ Bool
isLatest [([Char], Maybe [Char])]
addColumnEntries) <- [ExtendedIndividualInfo]
extIndInfos
Bool
True <- Bool -> [Bool]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Bool
not Bool
onlyLatest Bool -> Bool -> Bool
|| Bool
isLatest)
[[Char]] -> [[[Char]]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> a -> b
$ [[Char]
name, [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
", " [[Char]]
groups, ExtendedIndividualInfo -> [Char]
forall a. HasNameAndVersion a => a -> [Char]
getPacName ExtendedIndividualInfo
i,
Maybe Version -> [Char]
showMaybeVersion (ExtendedIndividualInfo -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion ExtendedIndividualInfo
i), Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
isLatest] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
(([Char], Maybe [Char]) -> [Char])
-> [([Char], Maybe [Char])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"n/a" (Maybe [Char] -> [Char])
-> (([Char], Maybe [Char]) -> Maybe [Char])
-> ([Char], Maybe [Char])
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], Maybe [Char]) -> Maybe [Char]
forall a b. (a, b) -> b
snd) [([Char], Maybe [Char])]
addColumnEntries
([[Char]], [[[Char]]]) -> ReaderT Env IO ([[Char]], [[[Char]]])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]]
tableH, [[[Char]]]
tableB)
ListBibliography AddColSpec
addColSpec -> do
[BibliographyInfo]
bibInfos <- case RepoLocationSpec
repoLocation of
RepoRemote (ArchiveEndpoint [Char]
remoteURL Maybe [Char]
archive) -> do
[Char] -> PoseidonIO ()
logInfo [Char]
"Downloading bibliography data from server"
let addJannoColFlag :: [Char]
addJannoColFlag = case AddColSpec
addColSpec of
AddColSpec
AddColAll -> [Char]
"&additionalBibColumns=ALL"
AddColList [] -> [Char]
""
AddColList [[Char]]
moreBibFields -> [Char]
"&additionalBibColumns=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"," [[Char]]
moreBibFields
ApiReturnData
apiReturn <- [Char] -> Bool -> PoseidonIO ApiReturnData
processApiResponse ([Char]
remoteURL [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/bibliography" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
qDefault Maybe [Char]
archive [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
addJannoColFlag) Bool
False
case ApiReturnData
apiReturn of
ApiReturnBibInfo [BibliographyInfo]
bibInfo -> [BibliographyInfo] -> ReaderT Env IO [BibliographyInfo]
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [BibliographyInfo]
bibInfo
ApiReturnData
_ -> [Char] -> ReaderT Env IO [BibliographyInfo]
forall a. HasCallStack => [Char] -> a
error [Char]
"should not happen"
RepoLocal [[Char]]
baseDirs -> do
[PoseidonPackage]
pacCollection <- PackageReadOptions -> [[Char]] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection PackageReadOptions
pacReadOpts [[Char]]
baseDirs
[PoseidonPackage]
-> AddColSpec -> ReaderT Env IO [BibliographyInfo]
forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> AddColSpec -> m [BibliographyInfo]
getBibliographyInfo [PoseidonPackage]
pacCollection AddColSpec
addColSpec
let addBibFieldNames :: [[Char]]
addBibFieldNames = case AddColSpec
addColSpec of
AddColSpec
AddColAll -> [[Char]] -> [[Char]]
forall a. Eq a => [a] -> [a]
nub ([[Char]] -> [[Char]])
-> ([BibliographyInfo] -> [[Char]])
-> [BibliographyInfo]
-> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BibliographyInfo -> [[Char]]) -> [BibliographyInfo] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((([Char], Maybe [Char]) -> [Char])
-> [([Char], Maybe [Char])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], Maybe [Char]) -> [Char]
forall a b. (a, b) -> a
fst ([([Char], Maybe [Char])] -> [[Char]])
-> (BibliographyInfo -> [([Char], Maybe [Char])])
-> BibliographyInfo
-> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BibliographyInfo -> [([Char], Maybe [Char])]
bibInfoAddCols) ([BibliographyInfo] -> [[Char]]) -> [BibliographyInfo] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ [BibliographyInfo]
bibInfos
AddColList [[Char]]
names -> [[Char]]
names
case AddColSpec
addColSpec of
AddColList ([Char]
_:[[Char]]
_) -> do
[[Char]] -> ([Char] -> PoseidonIO ()) -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [[Char]]
addBibFieldNames (([Char] -> PoseidonIO ()) -> PoseidonIO ())
-> ([Char] -> PoseidonIO ()) -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ \[Char]
bibFieldKey -> do
let nonEmptyEntries :: [()]
nonEmptyEntries = do
BibliographyInfo
bibInfo <- [BibliographyInfo]
bibInfos
Just (Just [Char]
_) <- Maybe (Maybe [Char]) -> [Maybe (Maybe [Char])]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Maybe [Char]) -> [Maybe (Maybe [Char])])
-> Maybe (Maybe [Char]) -> [Maybe (Maybe [Char])]
forall a b. (a -> b) -> a -> b
$ [Char]
bibFieldKey [Char] -> [([Char], Maybe [Char])] -> Maybe (Maybe [Char])
forall a b. Eq a => a -> [(a, b)] -> Maybe b
`lookup` BibliographyInfo -> [([Char], Maybe [Char])]
bibInfoAddCols BibliographyInfo
bibInfo
() -> [()]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [()]
nonEmptyEntries) (PoseidonIO () -> PoseidonIO ())
-> ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> PoseidonIO ()
logWarning ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$
[Char]
"Bibliography field " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
bibFieldKey [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"is not present in any bibliography entry"
AddColSpec
_ -> () -> PoseidonIO ()
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
let tableH :: [[Char]]
tableH = [[Char]
"BibKey", [Char]
"Title", [Char]
"Author", [Char]
"Year", [Char]
"DOI",
[Char]
"Nr of samples"] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]]
addBibFieldNames
tableB :: [[[Char]]]
tableB = do
BibliographyInfo
bibInfo <- [BibliographyInfo]
bibInfos
let addBibFieldColumns :: [[Char]]
addBibFieldColumns = do
[Char]
bibFieldName <- [[Char]]
addBibFieldNames
case [Char]
bibFieldName [Char] -> [([Char], Maybe [Char])] -> Maybe (Maybe [Char])
forall a b. Eq a => a -> [(a, b)] -> Maybe b
`lookup` BibliographyInfo -> [([Char], Maybe [Char])]
bibInfoAddCols BibliographyInfo
bibInfo of
Just (Just [Char]
v) -> [Char] -> [[Char]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
v
Maybe (Maybe [Char])
_ -> [Char] -> [[Char]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
""
[([Char], [Char])]
authors <- [Char] -> [[([Char], [Char])]]
forall (m :: * -> *).
MonadThrow m =>
[Char] -> m [([Char], [Char])]
parseAuthors ([Char] -> [[([Char], [Char])]])
-> (BibliographyInfo -> [Char])
-> BibliographyInfo
-> [[([Char], [Char])]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe [Char] -> [Char]
curateBibField (Maybe [Char] -> [Char])
-> (BibliographyInfo -> Maybe [Char]) -> BibliographyInfo -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BibliographyInfo -> Maybe [Char]
bibInfoAuthor (BibliographyInfo -> [[([Char], [Char])]])
-> BibliographyInfo -> [[([Char], [Char])]]
forall a b. (a -> b) -> a -> b
$ BibliographyInfo
bibInfo
[[Char]] -> [[[Char]]]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> a -> b
$ [BibliographyInfo -> [Char]
bibInfoKey BibliographyInfo
bibInfo, Maybe [Char] -> [Char]
curateBibField (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ BibliographyInfo -> Maybe [Char]
bibInfoTitle BibliographyInfo
bibInfo, [([Char], [Char])] -> [Char]
authorAbbrvString [([Char], [Char])]
authors,
Maybe [Char] -> [Char]
curateBibField (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ BibliographyInfo -> Maybe [Char]
bibInfoYear BibliographyInfo
bibInfo,
Maybe [Char] -> [Char]
curateBibField (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ BibliographyInfo -> Maybe [Char]
bibInfoDoi BibliographyInfo
bibInfo, Int -> [Char]
forall a. Show a => a -> [Char]
show (BibliographyInfo -> Int
bibInfoNrSamples BibliographyInfo
bibInfo)] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
[[Char]]
addBibFieldColumns
([[Char]], [[[Char]]]) -> ReaderT Env IO ([[Char]], [[[Char]]])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]]
tableH, [[[Char]]]
tableB)
if Bool
rawOutput then
IO () -> PoseidonIO ()
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> PoseidonIO ()) -> IO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"\n" [[Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"\t" [[Char]]
row | [[Char]]
row <- [[Char]]
tableH[[Char]] -> [[[Char]]] -> [[[Char]]]
forall a. a -> [a] -> [a]
:[[[Char]]]
tableB]
else do
let colSpecs :: [ColSpec]
colSpecs = Int -> ColSpec -> [ColSpec]
forall a. Int -> a -> [a]
replicate ([[Char]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Char]]
tableH) (LenSpec -> Position H -> AlignSpec -> CutMark -> ColSpec
column (Int -> LenSpec
expandUntil Int
60) Position H
forall a. Default a => a
def AlignSpec
forall a. Default a => a
def CutMark
forall a. Default a => a
def)
IO () -> PoseidonIO ()
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> PoseidonIO ()) -> IO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [ColSpec]
-> TableStyle -> HeaderSpec -> [RowGroup [Char]] -> [Char]
forall a.
Cell a =>
[ColSpec] -> TableStyle -> HeaderSpec -> [RowGroup a] -> [Char]
tableString [ColSpec]
colSpecs TableStyle
asciiRoundS ([[Char]] -> HeaderSpec
titlesH [[Char]]
tableH) [[[[Char]]] -> RowGroup [Char]
forall a. [Row a] -> RowGroup a
rowsG [[[Char]]]
tableB]
where
showMaybe :: Maybe String -> String
showMaybe :: Maybe [Char] -> [Char]
showMaybe = [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"n/a"
showMaybeVersion :: Maybe Version -> String
showMaybeVersion :: Maybe Version -> [Char]
showMaybeVersion = [Char] -> (Version -> [Char]) -> Maybe Version -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"n/a" Version -> [Char]
showVersion
curateBibField :: Maybe String -> String
curateBibField :: Maybe [Char] -> [Char]
curateBibField = Text -> [Char]
T.unpack (Text -> [Char])
-> (Maybe [Char] -> Text) -> Maybe [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
" " ([Text] -> Text)
-> (Maybe [Char] -> [Text]) -> Maybe [Char] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
T.strip ([Text] -> [Text])
-> (Maybe [Char] -> [Text]) -> Maybe [Char] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
T.lines (Text -> [Text])
-> (Maybe [Char] -> Text) -> Maybe [Char] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
T.pack ([Char] -> Text)
-> (Maybe [Char] -> [Char]) -> Maybe [Char] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
""
showContributor :: ContributorSpec -> String
showContributor :: ContributorSpec -> [Char]
showContributor (ContributorSpec [Char]
n [Char]
e Maybe ORCID
o) = [Char]
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" (" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
e [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
") ORCID: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> (ORCID -> [Char]) -> Maybe ORCID -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"n/a" ORCID -> [Char]
renderORCID Maybe ORCID
o