packages feed

bibdb-0.5.2: src/Database/Fetch.hs

-----------------------------------------------------------------------------
-- |
-- Module      : Database.Fetch
-- Description : Communication protocols for databases
-- Maintainer  : coskuacay@gmail.com
-- Stability   : experimental
-----------------------------------------------------------------------------
module Database.Fetch (fetch, fetchAll) where

import Control.Concurrent.Async
import Control.Monad.Except
import Control.Monad.IO.Class (MonadIO (..))

import Args (BibSize)
import Reference

import qualified Database.Doi as Doi
import qualified Database.Dblp as Dblp
import qualified Database.ArXiv as ArXiv
import qualified Database.Hal as Hal

import Utility.Except


fetch :: (MonadError String m, MonadIO m) => BibSize -> Source -> m (RefIdent, [BibTeX])
fetch size source@(Source t key) = do
  liftIO $ putStrLn $ "Fetching " ++ show source
  bibstr <- fetchString size key
  case parseBibTeX bibstr of
    Left err -> throwError $ "Error: cannot parse server response:\n" ++ err
    Right bibtex@(h : _) -> return (bibIdent h, bibtex)
    Right _ -> throwError $ "Error: empty response from server"
  where
    fetchString :: (MonadError String m, MonadIO m) => BibSize -> SourceKey -> m String
    fetchString = case t of
      Doi -> Doi.fetchString
      Dblp -> Dblp.fetchString
      ArXiv -> ArXiv.fetchString
      Hal -> Hal.fetchString
      Inria -> \size key -> Hal.fetchString size (inriaToHalKey key)
      _ -> undefined

    inriaToHalKey :: SourceKey -> SourceKey
    inriaToHalKey (SourceKey key) = SourceKey ("inria-" ++ key)


fetchAll :: (MonadError String m, MonadIO m) => BibSize -> [Source] -> m ([RefIdent], [BibTeX])
fetchAll size srcs = do
  maybeResults <- liftIO $ mapConcurrently (runExceptT . fetch size) srcs
  results <- liftEither $ sequence maybeResults
  let (idents, bibs) = unzip results
  return (idents, concat bibs)