rpm-0.0.1: System/Rpm/Info.hs
{-|
This module is mainly for internal purposes and these functions
should not be called directly.
-- Remove 'testName'
-}
module System.Rpm.Info
( RpmInfo(..)
, rpmInfoFromFile
, rpmInfoFromXml
) where
import Text.XML.HaXml hiding (version)
import Text.XML.HaXml.Posn (Posn)
import System.Rpm.Xml (executeRpm2Xml)
data RpmInfo = RpmI {
name :: String
, buildHost :: String
, buildTime :: Integer
, description :: String
, summary :: String
, size :: Integer
, version :: String
, release :: String
} deriving(Show, Eq)
--------------------------------------------------------------------------------
runFilter :: CFilter i -- ^ Function like 'getName'
-> [Content i] -- ^ Usually the children of the root element.
-> [Maybe String] -- ^ The extracted text, if any.
runFilter f = map extractText . concatMap f
{-| 'rpmFilter' is a function that creates a 'CFilter' that matches elements similar to:
@\<rpmTag name=QueryTag>
\<TagType>\</TagType>
\</rpmTag>@
-}
rpmFilter :: String -- ^ Tag Name
-> String -- ^ Tag Type
-> CFilter i
rpmFilter tagName tagType c = (txt `o` children `o` tag tagType `o` children `o` attrval att `o` tag "rpmTag") c
where
att :: Attribute
att = ("name", AttValue [Left tagName])
{-|
getName is a filter for extracting string elements from tags with
Name attributes. The other functions are typically the same
unless otherwise noted. -}
getName :: CFilter i
getName = rpmFilter "Name" "string"
getBuildHost :: CFilter i
getBuildHost = rpmFilter "Buildhost" "string"
getBuildTime :: CFilter i
getBuildTime = rpmFilter "Buildtime" "integer"
getDescription :: CFilter i
getDescription = rpmFilter "Description" "string"
getSummary :: CFilter i
getSummary = rpmFilter "Summary" "string"
getSize :: CFilter i
getSize = rpmFilter "Size" "integer"
getVersion :: CFilter i
getVersion = rpmFilter "Version" "string"
getRelease :: CFilter i
getRelease = rpmFilter "Release" "string"
getURL :: CFilter i
getURL = rpmFilter "Url" "string"
getArch :: CFilter i
getArch = rpmFilter "Arch" "string"
getArchiveSize :: CFilter i
getArchiveSize = rpmFilter "Archivesize" "integer"
--------------------------------------------------------------------------------
getRpmInfo :: [Content i]
-> Maybe RpmInfo
getRpmInfo cs = do
n <- extract getName
s <- extract getSummary
d <- extract getDescription
bh <- extract getBuildHost
bt <- extract getBuildTime
sz <- extract getSize
v <- extract getVersion
r <- extract getRelease
return RpmI { name = n
, summary = s
, description = d
, buildHost = bh
, size = read sz :: Integer
, buildTime = read bt :: Integer
, version = v
, release = r }
where
extract f = let results = runFilter f cs in
if null results
then Nothing
else head results
rpmInfoFromFile :: FilePath -- ^ Path to a Rpm
-> IO (Maybe RpmInfo)
rpmInfoFromFile file = do
contents <- executeRpm2Xml file
case contents of
Just xml -> return (rpmInfoFromXml xml)
Nothing -> return Nothing
rpmInfoFromXml :: String -- ^ A string of XML containing information about a package.
-> Maybe RpmInfo
rpmInfoFromXml xml = getRpmInfo (content xml)
where content file = extractContent ( getRootElement file file)
getRootElement :: String -- ^ Filename to report parsing errors for.
-> String -- ^ String of XML Content
-> Element Posn
getRootElement fileName xml = elt
where Document _ _ elt _ = xmlParse xml fileName
extractContent :: Element i -> [Content i]
extractContent (Elem _ _ c ) = c
extractText :: Content i -> Maybe String
extractText e = case e of
CString _ n _ -> Just n
_ -> Nothing