module Distribution.ArchLinux.AUR.RPC
( info
, searchBy
, search
) where
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as Text
import Data.Text (Text)
import Control.Monad.Except
import Control.Monad.Catch
import Network.HTTP.Client
import Network.HTTP.Client.TLS
import Data.Aeson
import Distribution.ArchLinux.AUR.Types
aurServer = "https://aur.archlinux.org/rpc/?v=" ++ show aurApi
where aurApi = 5
genURL :: AURQuery -> String
genURL (QSearch field txt) = aurServer ++ "&type=search&by=" ++ show field ++ "&arg=" ++ txt
genURL (QInfo q) = aurServer ++ "&type=info" ++ concatMap (\x -> "&arg%5b%5d="++x) q
get s = join $ liftM2 httpLbs (parseUrl (genURL s)) (newManager tlsManagerSettings)
getM :: (MonadIO m) => AURQuery -> ExceptT String m (Response LBS.ByteString)
getM s = ExceptT . liftIO $ fmap Right (get s) `catch` (\(SomeException e) -> return (Left (show e)))
queryAUR :: (MonadIO m) => AURQuery -> ExceptT String m [AURInfo]
queryAUR s = getM s >>= \r -> ExceptT . return $ (eitherDecode >=> getAURInfo) (responseBody r)
concatMapM :: (Monad m, Foldable t) => (a -> m [b]) -> t a -> m [b]
concatMapM op = foldr f (return [])
where
f x xs = do x <- op x
if null x then xs else fmap (x ++) xs
info :: (MonadIO m) => [String] -> ExceptT String m [AURInfo]
info = concatMapM (queryAUR . QInfo) . chunks
chunks :: [String] -> [[String]]
chunks s = if null s then [] else s1 : chunks s'
where (s1, s') = splitAt 1024 s
searchBy :: (MonadIO m) => SearchBy -> String -> ExceptT String m [AURInfo]
searchBy f = queryAUR . QSearch f
search :: (MonadIO m) => String -> ExceptT String m [AURInfo]
search = searchBy ByNameDesc
url1 = "https://aur.archlinux.org/rpc/?v=5&type=info&arg%5b%5d=icaclient"