import Control.Monad import Data.Char (toLower) import Text.Printf (printf) import Crypto.Hash.SHA1 (hash) import System.Environment (getArgs) import System.Directory import System.FilePath.Posix import qualified Data.ByteString as B getDirectoryFiles :: FilePath -> IO [FilePath] getDirectoryFiles path = map (path ) <$> getDirectoryContents path >>= filterM doesFileExist fileHash :: FilePath -> IO String fileHash = fmap (hex . hash) . B.readFile hex :: B.ByteString -> String hex bytes = B.unpack bytes >>= printf "%02X" newName :: FilePath -> IO FilePath newName path = do hash <- take 10 <$> fileHash path let (file, ext) = splitExtension path (dir, base) = splitFileName file new = dir hash <.> map toLower ext if null base then return path else return new main :: IO () main = do args <- getArgs path <- case args of [] -> getCurrentDirectory x:_ -> return x putStrLn ("Renaming files in " ++ path) files <- getDirectoryFiles path names <- mapM newName files forM (zip files names) $ \(x, y) -> do let x' = takeFileName x y' = takeFileName y putStrLn (printf "%s -> %s" x' y') renameFile x y putStrLn "Files renamed successfully"