packages feed

hashrename-0.1.1.0: Main.hs

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"