44 lines
1.2 KiB
Haskell
44 lines
1.2 KiB
Haskell
import Control.Applicative
|
|
import Control.Monad
|
|
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 <.> ext
|
|
if null base
|
|
then return path
|
|
else return new
|
|
|
|
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" |