//go:binary-only-package
package main
import (
"crypto/sha256"
"path/filepath"
"fmt"
"io"
"io/ioutil"
"strings"
//"log"
"os"
)
var keepLongExt bool = false
var fake bool = false
var recurse bool = false
var noErr bool = false
func last ( str [ ] string ) string {
if ( len ( str ) < 1 ) {
return ""
} else {
return fmt . Sprintf ( ".%s" , str [ len ( str ) - 1 ] )
}
}
func hash ( file string ) [ ] byte {
f , err := os . Open ( file )
if err != nil {
fmt . Printf ( "E: Cannot open file: %s" , err ) ;
}
defer f . Close ( )
h := sha256 . New ( )
if _ , err := io . Copy ( h , f ) ; err != nil {
fmt . Printf ( "E: Cannot create hash: %s" , err ) ;
}
return h . Sum ( nil )
}
func extractExt ( x string ) string {
if ( keepLongExt ) {
return last ( strings . SplitN ( x , "." , 2 ) [ 1 : ] )
} else {
return filepath . Ext ( x )
}
}
func dofile ( i int , y string ) {
loc , x := filepath . Split ( y )
sha := hash ( y )
str := fmt . Sprintf ( "%x" , sha )
newname := fmt . Sprintf ( "%s%s%s" , loc , str , extractExt ( x ) )
if _ , err := os . Stat ( newname ) ; ! os . IsNotExist ( err ) {
if ( ! noErr ) {
fmt . Printf ( "E: (%d) %s: %s alread exists.\n" , i , y , newname )
}
} else {
if ! fake {
os . Rename ( y , newname )
}
fmt . Printf ( "(%d) %s -> %s\n" , i , y , newname )
}
}
func main ( ) {
ar := os . Args [ 1 : ] ;
if ( len ( ar ) < 1 ) {
fmt . Printf ( "Usage: %s [--long] [--fake] [--recurse] [-quiet] <file ...>\n\t--long\tKeep long file extensions\n\t--fake\tDo not rename files.\n\t--recurse\tWalk path recursively.\n\t--quiet\tDo not show (some) errors.\n" , os . Args [ 0 ] )
return ;
}
for i , x := range ar {
if ( strings . HasPrefix ( x , "--" ) ) {
switch x [ 2 : ] {
case "long" :
keepLongExt = ! keepLongExt
case "fake" :
fake = ! fake
case "recurse" :
recurse = ! recurse
case "quiet" :
noErr = ! noErr
default :
fmt . Printf ( "Unknown flag \"%s\"\n" , x )
}
} else {
if fi , err := os . Stat ( x ) ; os . IsNotExist ( err ) {
fmt . Printf ( "(%d) %s does not exist.\n" , i , x )
} else {
if ( fi . Mode ( ) . IsDir ( ) ) {
if ( recurse ) {
filepath . Walk ( x , func ( path string , f os . FileInfo , err error ) error {
if ( ! f . Mode ( ) . IsDir ( ) ) {
dofile ( i , path )
}
return nil
} )
} else {
files , err := ioutil . ReadDir ( x )
if err != nil {
fmt . Printf ( "E: Error enumerating files: %s\n" , err )
} else {
for _ , f := range files {
if ( ! f . Mode ( ) . IsDir ( ) ) {
fl := fmt . Sprintf ( "%s/%s" , x , f . Name ( ) )
dofile ( i , fl )
} else {
fmt . Printf ( "!: Ignoring %s (is directory)\n" , f . Name ( ) )
}
}
}
}
} else {
dofile ( i , x )
}
}
}
}
return ;
}