module Main where import Data.Maybe import Data.List import Data.List.Split import System.Process import Data.Time.Parse import Data.Time.LocalTime import Data.Time.ISO8601 import qualified Data.Text as T ---------------- coalesce :: (a -> a -> Maybe a) -> [a] -> [a] coalesce f x = case x of (p:q:x') -> case f p q of Nothing -> p : coalesce f (q : x') Just r -> coalesce f (r : x') _ -> x fromRight :: Either a b -> b fromRight (Right x) = x strip :: String -> String strip = T.unpack . T.strip . T.pack ---------------- type Entry = (String, String) type Package = [Entry] pacmanQueryInfoRaw :: IO String pacmanQueryInfoRaw = readProcess "pacman" ["-Qi"] [] pacmanQueryInfo :: IO [Package] pacmanQueryInfo = parsePackageList <$> pacmanQueryInfoRaw parsePackageList :: String -> [Package] parsePackageList input = map parsePackage blocks where blocks = endBy "\n\n" input parsePackage :: String -> Package parsePackage input = map fromRight $ coalesce joiner entries where inputLines = lines input entries = map parsePackageEntry inputLines joiner (Right (title, value)) (Left value') = Just $ Right (title, value ++ " " ++ value') joiner _ _ = Nothing parsePackageEntry :: String -> Either String Entry parsePackageEntry input = case break (== ':') input of (value, []) -> Left $ strip value (title, (_:value)) -> Right (strip title, strip value) packageEntryValue :: String -> Package -> String packageEntryValue key = fromJust . lookup key packageName :: Package -> String packageName = packageEntryValue "Name" packageVersion :: Package -> String packageVersion = packageEntryValue "Version" packageInstallDate :: Package -> String packageInstallDate = formatPackageDate . packageEntryValue "Install Date" formatPackageDate :: String -> String formatPackageDate input = formatISO8601 $ localTimeToUTC utc time where Just (time, _) = strptime "%a %d %b %Y %I:%M:%S %p" input formatPackage :: Package -> String formatPackage package = intercalate " " [installDate, name, version] where name = packageName package version = packageVersion package installDate = packageInstallDate package main = do { packages <- pacmanQueryInfo ; putStrLn $ unlines $ map formatPackage packages }