packages feed

ldif 0.0.12 → 0.0.13

raw patch · 11 files changed

+247/−224 lines, 11 filesdep +ldifPVP ok

version bump matches the API change (PVP)

Dependencies added: ldif

API changes (from Hackage documentation)

Files

+ cmd/ldif2html.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE BangPatterns, OverloadedStrings #-}+-- | Make Change LDIF based on two Content LDIFs+import Data.List+import Data.Either+import Data.Maybe+import Control.Monad +import System.FilePath +import System.Environment+import Text.LDIF+import qualified Data.Set as Set+import qualified Data.ByteString.Char8 as BC++-- | Serialize DN to LDIF Format+dn2html :: DN -> BC.ByteString+dn2html ys@(DN xs) = BC.concat [ "<div id=\"abc" +                               , nm +                               , "\"></div><b>dn:</b> <font color=\"green\"><b>" +                               , dnstr +                               , "</b></font>" ]+      where+        dnstr = BC.intercalate "," $ map (\((Attribute n),v) -> n `BC.append` "=" `BC.append` (aVal v)) xs+        nm = aVal $ dn2last ys++-- | Serialize Change Record in LDIF Format+record2html :: Set.Set Value -> LDIFRecord -> BC.ByteString+record2html idx (ChangeRecord dn (ChangeDelete))     = BC.unlines   [ (dn2str dn), "changetype: delete" ]+record2html idx (ChangeRecord dn (ChangeAdd xs))     = BC.unlines $ [ (dn2html dn), "changetype: add"    ] ++ (attrVals2Ln idx xs)+record2html idx (ChangeRecord dn (ChangeModify xs))  = BC.unlines $ [ (dn2str dn), "changetype: modify" ] ++ (mods2Ln idx xs)+record2html idx (ChangeRecord dn (ChangeModDN))      = BC.unlines $ [ (dn2str dn), "changetype: moddn"  ]+record2html idx (ContentRecord dn xs) = BC.unlines $ [ (dn2html dn) ] ++ (attrVals2Ln idx xs)++attrVals2Ln :: Set.Set Value -> [AttrValue] -> [BC.ByteString]+attrVals2Ln idx xs = map (attrVal2Ln idx) xs++attrVal2Ln :: Set.Set Value -> AttrValue -> BC.ByteString+attrVal2Ln idx ((Attribute n),v) = if Set.member v idx then BC.concat [ "<b>"+                                                                      , n +                                                                      , "</b> : <a href=\"#abc"+                                                                      , aVal v+                                                                      , "\">" +                                                                      , aVal v+                                                                      , "</a>"]+                          else BC.concat [ "<b>",n,"</b> : ",aVal v]++mods2Ln :: Set.Set Value -> [Modify] -> [BC.ByteString]+mods2Ln idx xs = intercalate ["-"] $ map (mod2Ln idx) xs++mod2Ln :: Set.Set Value -> Modify -> [BC.ByteString]+mod2Ln idx mod = [ attrVal2Ln idx (modName,attrName) ] ++ valLst+  where+    attrName = Value $ aName $ modAttr mod+    valLst = map (\v -> attrVal2Ln idx (modAttr mod,v)) $ modAttrVals mod+    modName = case mod of +      (ModAdd _ _)     -> Attribute "add"+      (ModDelete _ _)  -> Attribute "delete"+      (ModReplace _ _) -> Attribute "replace"++dns :: LDIF -> Set.Set Value+dns (LDIF _ xs) = Set.fromList $ nub $ map (dn2last . reDN) xs++dn2last (DN xs) = snd $ head xs++main = do+  args <- getArgs+  case args of +     []         -> putStrLn "Usage: ldif2html <input.ldif> [<input2.ldif> <input3.ldif> ... <inputN.ldif> <output.ldif>]"+     [inp]      -> do+                      doLDIF2HTML [inp] (BC.putStrLn)+                      putStrLn "# Done."+     xs         -> do+                      doLDIF2HTML (init xs) (BC.writeFile (last xs)) +                      putStrLn $ "## Processed : " ++ (unlines $ init xs)+                      putStrLn $ "## Written   : " ++ (last xs)+  where+    doLDIF2HTML names outF = do+      mls <- mapM (parseLDIFFile defaulLDIFConf) names+      case lefts mls of +        []   -> do+                let idx = Set.unions $ map dns $ rights mls+                outF $ BC.concat [ "<html><body bgcolor=lightyellow><pre>"+                                 , BC.concat $ map (ldif2html idx) (rights mls) +                                 , "</pre></body></html>" ]+        xs  -> mapM_ print xs+      -- | Serialize LDIF to HTML+    ldif2html :: Set.Set Value -> LDIF -> BC.ByteString+    ldif2html idx (LDIF v xs) = BC.unlines $ (ver2str v) ++ (map (record2html idx) xs)++
+ cmd/ldifdiff.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE DeriveDataTypeable #-}+-- | Make Change LDIF based on two Content LDIFs+import Data.List+import Data.Either+import Data.Maybe+import Control.Monad +import System.FilePath +import System.Environment+import Text.LDIF+import System.Console.CmdArgs+import qualified Data.ByteString.Char8 as BC++progDesc = "Create delta LDIF between Source LDIF and Target LDIF"++data LdifDiff = LdifDiff { srcFile :: FilePath+                         , dstFile :: FilePath } deriving (Show, Data, Typeable)++defaultCfg = LdifDiff { srcFile = def &= typFile &= name "s" &= help "Source LDIF File"+                      , dstFile = def &= typFile &= name "t" &= help "Target LDIF File" }++main = do+  cfg <- cmdArgs defaultCfg+  execute cfg++execute (LdifDiff []  _  ) = putStrLn "Error: -s source file is mandatory" +execute (LdifDiff _ []   ) = putStrLn "Error: -t target file is mandatory"+execute (LdifDiff src dst) = do+  ml1 <- parseLDIFFile defaulLDIFConf src+  ml2 <- parseLDIFFile defaulLDIFConf dst+  case rights [ml1,ml2] of +       [l1,l2] -> case diffLDIF l1 l2 of+                    Left err -> putStrLn err+                    Right delta -> BC.putStrLn $ ldif2str delta+       _       -> print $ lefts [ml1,ml2] 
+ cmd/ldifmodify.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}+-- | Apply LDAP operations within LDIF on another LDIF.+-- | Without schema related verification like syntax, cardinality etc.+import Data.List+import Data.Either+import Data.Maybe+import Control.Monad +import System.FilePath +import System.Environment+import Text.LDIF+import System.Console.CmdArgs+import qualified Data.ByteString.Char8 as BC++progDesc = "Apply LDAP operations from LDIF to LDIF (like ldapmodify)"++data LdifModify = LdifModify { baseFile :: FilePath+                             , modFiles  :: [FilePath]+                             , outFile  :: FilePath } deriving (Show, Data, Typeable)++defaultCfg = LdifModify { baseFile = def &= typFile &= name "f" &= help "Base LDIF File"+                        , modFiles = def &= args &= typ "LDIF Files for applying"+                        , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }++main = do+  cfg <- cmdArgs defaultCfg+  execute cfg++execute (LdifModify [] _ _) = putStrLn "Error: -f base LDIF File is mandatory"+execute (LdifModify _ [] _) = putStrLn "Error: no LDIF Files for applying provided"+execute (LdifModify _ _ []) = putStrLn "Error: -o output LDIF File is mandatory"+execute cfg = do+  baseLDIF <- safeParseLDIFFile (baseFile cfg)+  modLDIFs <- mapM (safeParseLDIFFile) (modFiles cfg)+  let outLDIF = foldr (flip applyLDIF) baseLDIF modLDIFs+  if length (outFile cfg) == 0 then do+      BC.putStrLn (ldif2str outLDIF)+    else do+      BC.writeFile (outFile cfg) (ldif2str outLDIF)+      putStrLn $ (outFile cfg) ++ " written."++safeParseLDIFFile :: FilePath -> IO LDIF+safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
+ cmd/ldifparse.hs view
@@ -0,0 +1,17 @@+-- | Make Change LDIF based on two Content LDIFs+import Data.List+import Data.Either+import Data.Maybe+import Control.Monad +import System.FilePath +import System.Environment+import Text.LDIF+import qualified Data.ByteString.Char8 as BC++main = do+  args <- getArgs+  let name = args !! 0+  ml1 <- parseLDIFFile defaulLDIFConf name+  case ml1 of +       Right l1 -> BC.putStrLn $ ldif2str l1+       Left err -> print err
+ cmd/ldifundo.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}+import Data.List+import Data.Either+import Data.Maybe+import Control.Monad+import System.FilePath+import System.Environment+import Text.LDIF+import System.Console.CmdArgs+import qualified Data.ByteString.Char8 as BC++progDesc = "Calculate undo LDIF (rollback LDIF)"++data LdifUndo = LdifUndo { inFile   :: FilePath+                         , outFile  :: FilePath } deriving (Show, Data, Typeable)++defaultCfg = LdifUndo { inFile = def &= typFile &= name "f" &= help "Input LDIF File"+                      , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }++main = do+  cfg <- cmdArgs defaultCfg+  execute cfg++execute (LdifUndo [] _) = putStrLn "Error: -f base LDIF File is mandatory"+execute cfg = do+  inLDIF <- safeParseLDIFFile (inFile cfg)+  let (outLDIF, wrn) = undoLDIF inLDIF+  when (not $ null wrn) (putStrLn $ "Finished with warnings: " ++ (unlines $ map unlines wrn))+  if length (outFile cfg) == 0 then do+      BC.putStrLn (ldif2str outLDIF)+    else do+      BC.writeFile (outFile cfg) (ldif2str outLDIF)+      putStrLn $ (outFile cfg) ++ " written."++safeParseLDIFFile :: FilePath -> IO LDIF+safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
ldif.cabal view
@@ -1,5 +1,5 @@ Name:            ldif-Version:         0.0.12+Version:         0.0.13 License:         BSD3 License-File:    LICENSE Synopsis:        The LDAP Data Interchange Format (LDIF) tools @@ -20,6 +20,8 @@  .  - ldifmodify - replays delta LDIF operations on content LDIF (similar to ldapmodify).  .+ - ldifundo - produces delta LDIF which rollbacks operations in input LDIF.+ . Category:        Text Stability:       experimental Build-Type:      Simple@@ -50,7 +52,7 @@  flag cmd   description: Build command line programs.-  default:     False+  default:     True  Library   Build-Depends:   base         < 5,@@ -79,7 +81,12 @@         Text.LDIF.Undo  Executable ldifdiff-  Hs-Source-Dirs:  src+  Hs-Source-Dirs:  cmd+  Build-Depends:   base         < 5,+                   ldif,+                   cmdargs,+                   filepath,+                   bytestring   Main-Is:         ldifdiff.hs   if flag(cmd)     Buildable:     True@@ -89,7 +96,13 @@     Buildable:     False  Executable ldif2html-  Hs-Source-Dirs:  src+  Hs-Source-Dirs:  cmd+  Build-Depends:   base         < 5,+                   ldif,+                   containers,+                   cmdargs,+                   filepath,+                   bytestring   Main-Is:         ldif2html.hs   if flag(cmd)     Buildable:     True@@ -99,7 +112,12 @@     Buildable:     False  Executable ldifmodify-  Hs-Source-Dirs:  src+  Hs-Source-Dirs:  cmd+  Build-Depends:   base         < 5,+                   ldif,+                   cmdargs,+                   filepath,+                   bytestring   Main-Is:         ldifmodify.hs   if flag(cmd)     Buildable:     True@@ -109,7 +127,12 @@     Buildable:     False  Executable ldifundo-  Hs-Source-Dirs:  src+  Hs-Source-Dirs:  cmd+  Build-Depends:   base         < 5,+                   ldif,+                   cmdargs,+                   filepath,+                   bytestring   Main-Is:         ldifundo.hs   if flag(cmd)     Buildable:     True@@ -119,7 +142,7 @@     Buildable:     False  Executable ldifparse-  Hs-Source-Dirs:  src+  Hs-Source-Dirs:  cmd   Main-Is:         ldifparse.hs   if !flag(test)     Buildable:     False
− src/ldif2html.hs
@@ -1,88 +0,0 @@-{-# LANGUAGE BangPatterns, OverloadedStrings #-}--- | Make Change LDIF based on two Content LDIFs-import Data.List-import Data.Either-import Data.Maybe-import Control.Monad -import System.FilePath -import System.Environment-import Text.LDIF-import qualified Data.Set as Set-import qualified Data.ByteString.Char8 as BC---- | Serialize DN to LDIF Format-dn2html :: DN -> BC.ByteString-dn2html ys@(DN xs) = BC.concat [ "<div id=\"abc" -                               , nm -                               , "\"></div><b>dn:</b> <font color=\"green\"><b>" -                               , dnstr -                               , "</b></font>" ]-      where-        dnstr = BC.intercalate "," $ map (\((Attribute n),v) -> n `BC.append` "=" `BC.append` (aVal v)) xs-        nm = aVal $ dn2last ys---- | Serialize Change Record in LDIF Format-record2html :: Set.Set Value -> LDIFRecord -> BC.ByteString-record2html idx (ChangeRecord dn (ChangeDelete))     = BC.unlines   [ (dn2str dn), "changetype: delete" ]-record2html idx (ChangeRecord dn (ChangeAdd xs))     = BC.unlines $ [ (dn2html dn), "changetype: add"    ] ++ (attrVals2Ln idx xs)-record2html idx (ChangeRecord dn (ChangeModify xs))  = BC.unlines $ [ (dn2str dn), "changetype: modify" ] ++ (mods2Ln idx xs)-record2html idx (ChangeRecord dn (ChangeModDN))      = BC.unlines $ [ (dn2str dn), "changetype: moddn"  ]-record2html idx (ContentRecord dn xs) = BC.unlines $ [ (dn2html dn) ] ++ (attrVals2Ln idx xs)--attrVals2Ln :: Set.Set Value -> [AttrValue] -> [BC.ByteString]-attrVals2Ln idx xs = map (attrVal2Ln idx) xs--attrVal2Ln :: Set.Set Value -> AttrValue -> BC.ByteString-attrVal2Ln idx ((Attribute n),v) = if Set.member v idx then BC.concat [ "<b>"-                                                                      , n -                                                                      , "</b> : <a href=\"#abc"-                                                                      , aVal v-                                                                      , "\">" -                                                                      , aVal v-                                                                      , "</a>"]-                          else BC.concat [ "<b>",n,"</b> : ",aVal v]--mods2Ln :: Set.Set Value -> [Modify] -> [BC.ByteString]-mods2Ln idx xs = intercalate ["-"] $ map (mod2Ln idx) xs--mod2Ln :: Set.Set Value -> Modify -> [BC.ByteString]-mod2Ln idx mod = [ attrVal2Ln idx (modName,attrName) ] ++ valLst-  where-    attrName = Value $ aName $ modAttr mod-    valLst = map (\v -> attrVal2Ln idx (modAttr mod,v)) $ modAttrVals mod-    modName = case mod of -      (ModAdd _ _)     -> Attribute "add"-      (ModDelete _ _)  -> Attribute "delete"-      (ModReplace _ _) -> Attribute "replace"--dns :: LDIF -> Set.Set Value-dns (LDIF _ xs) = Set.fromList $ nub $ map (dn2last . reDN) xs--dn2last (DN xs) = snd $ head xs--main = do-  args <- getArgs-  case args of -     []         -> putStrLn "Usage: ldif2html <input.ldif> [<input2.ldif> <input3.ldif> ... <inputN.ldif> <output.ldif>]"-     [inp]      -> do-                      doLDIF2HTML [inp] (BC.putStrLn)-                      putStrLn "# Done."-     xs         -> do-                      doLDIF2HTML (init xs) (BC.writeFile (last xs)) -                      putStrLn $ "## Processed : " ++ (unlines $ init xs)-                      putStrLn $ "## Written   : " ++ (last xs)-  where-    doLDIF2HTML names outF = do-      mls <- mapM (parseLDIFFile defaulLDIFConf) names-      case lefts mls of -        []   -> do-                let idx = Set.unions $ map dns $ rights mls-                outF $ BC.concat [ "<html><body bgcolor=lightyellow><pre>"-                                 , BC.concat $ map (ldif2html idx) (rights mls) -                                 , "</pre></body></html>" ]-        xs  -> mapM_ print xs-      -- | Serialize LDIF to HTML-    ldif2html :: Set.Set Value -> LDIF -> BC.ByteString-    ldif2html idx (LDIF v xs) = BC.unlines $ (ver2str v) ++ (map (record2html idx) xs)--
− src/ldifdiff.hs
@@ -1,34 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}--- | Make Change LDIF based on two Content LDIFs-import Data.List-import Data.Either-import Data.Maybe-import Control.Monad -import System.FilePath -import System.Environment-import Text.LDIF-import System.Console.CmdArgs-import qualified Data.ByteString.Char8 as BC--progDesc = "Create delta LDIF between Source LDIF and Target LDIF"--data LdifDiff = LdifDiff { srcFile :: FilePath-                         , dstFile :: FilePath } deriving (Show, Data, Typeable)--defaultCfg = LdifDiff { srcFile = def &= typFile &= name "s" &= help "Source LDIF File"-                      , dstFile = def &= typFile &= name "t" &= help "Target LDIF File" }--main = do-  cfg <- cmdArgs defaultCfg-  execute cfg--execute (LdifDiff []  _  ) = putStrLn "Error: -s source file is mandatory" -execute (LdifDiff _ []   ) = putStrLn "Error: -t target file is mandatory"-execute (LdifDiff src dst) = do-  ml1 <- parseLDIFFile defaulLDIFConf src-  ml2 <- parseLDIFFile defaulLDIFConf dst-  case rights [ml1,ml2] of -       [l1,l2] -> case diffLDIF l1 l2 of-                    Left err -> putStrLn err-                    Right delta -> BC.putStrLn $ ldif2str delta-       _       -> print $ lefts [ml1,ml2] 
− src/ldifmodify.hs
@@ -1,42 +0,0 @@-{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}--- | Apply LDAP operations within LDIF on another LDIF.--- | Without schema related verification like syntax, cardinality etc.-import Data.List-import Data.Either-import Data.Maybe-import Control.Monad -import System.FilePath -import System.Environment-import Text.LDIF-import System.Console.CmdArgs-import qualified Data.ByteString.Char8 as BC--progDesc = "Apply LDAP operations from LDIF to LDIF (like ldapmodify)"--data LdifModify = LdifModify { baseFile :: FilePath-                             , modFiles  :: [FilePath]-                             , outFile  :: FilePath } deriving (Show, Data, Typeable)--defaultCfg = LdifModify { baseFile = def &= typFile &= name "f" &= help "Base LDIF File"-                        , modFiles = def &= args &= typ "LDIF Files for applying"-                        , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }--main = do-  cfg <- cmdArgs defaultCfg-  execute cfg--execute (LdifModify [] _ _) = putStrLn "Error: -f base LDIF File is mandatory"-execute (LdifModify _ [] _) = putStrLn "Error: no LDIF Files for applying provided"-execute (LdifModify _ _ []) = putStrLn "Error: -o output LDIF File is mandatory"-execute cfg = do-  baseLDIF <- safeParseLDIFFile (baseFile cfg)-  modLDIFs <- mapM (safeParseLDIFFile) (modFiles cfg)-  let outLDIF = foldr (flip applyLDIF) baseLDIF modLDIFs-  if length (outFile cfg) == 0 then do-      BC.putStrLn (ldif2str outLDIF)-    else do-      BC.writeFile (outFile cfg) (ldif2str outLDIF)-      putStrLn $ (outFile cfg) ++ " written."--safeParseLDIFFile :: FilePath -> IO LDIF-safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)
− src/ldifparse.hs
@@ -1,17 +0,0 @@--- | Make Change LDIF based on two Content LDIFs-import Data.List-import Data.Either-import Data.Maybe-import Control.Monad -import System.FilePath -import System.Environment-import Text.LDIF-import qualified Data.ByteString.Char8 as BC--main = do-  args <- getArgs-  let name = args !! 0-  ml1 <- parseLDIFFile defaulLDIFConf name-  case ml1 of -       Right l1 -> BC.putStrLn $ ldif2str l1-       Left err -> print err
− src/ldifundo.hs
@@ -1,36 +0,0 @@-{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}-import Data.List-import Data.Either-import Data.Maybe-import Control.Monad-import System.FilePath-import System.Environment-import Text.LDIF-import System.Console.CmdArgs-import qualified Data.ByteString.Char8 as BC--progDesc = "Calculate undo LDIF (rollback LDIF)"--data LdifUndo = LdifUndo { inFile   :: FilePath-                         , outFile  :: FilePath } deriving (Show, Data, Typeable)--defaultCfg = LdifUndo { inFile = def &= typFile &= name "f" &= help "Input LDIF File"-                      , outFile = def &= typFile &= name "o" &= help "Output LDIF File" }--main = do-  cfg <- cmdArgs defaultCfg-  execute cfg--execute (LdifUndo [] _) = putStrLn "Error: -f base LDIF File is mandatory"-execute cfg = do-  inLDIF <- safeParseLDIFFile (inFile cfg)-  let (outLDIF, wrn) = undoLDIF inLDIF-  when (not $ null wrn) (putStrLn $ "Finished with warnings: " ++ (unlines $ map unlines wrn))-  if length (outFile cfg) == 0 then do-      BC.putStrLn (ldif2str outLDIF)-    else do-      BC.writeFile (outFile cfg) (ldif2str outLDIF)-      putStrLn $ (outFile cfg) ++ " written."--safeParseLDIFFile :: FilePath -> IO LDIF-safeParseLDIFFile name = liftM (either (\e -> error $ "Can not parse: "++(show e)) (id)) (parseLDIFFile defaulLDIFConf name)