package main import ( "fmt" "os" "path/filepath" "porg/fileop" "porg/pipe" ) type SHAInfo struct { path string sha256 string } type File struct { Path string SHA256 string Time string } type MoveCommand struct { src string dest string } func Calculate(file string) *SHAInfo { f, err := os.Open(file) if err != nil { fmt.Println(err) return nil } defer f.Close() sha, err := fileop.CalculateSHA256(f) if err != nil { fmt.Println(err) return nil } else { return &SHAInfo{path: file, sha256: sha} } } func Move(base string) func(*SHAInfo) *MoveCommand { return func(info *SHAInfo) *MoveCommand { ext := filepath.Ext(info.path) head := info.sha256[0:2] tail := info.sha256[2:] newPath := fmt.Sprintf("%s/%s/%s%s", base, head, tail, ext) return &MoveCommand{src: info.path, dest: newPath} } } func Delete(path string) { empty, err := fileop.IsEmpty(path) if err != nil { fmt.Printf("Error reading %s: %s\n", path, err.Error()) } if empty { err := os.Remove(path) if err != nil { fmt.Printf("Error deleting %s: %s\n", path, err.Error()) } else { fmt.Printf("Folder deleted %s\n", path) } } } func Apply(move *MoveCommand) { dir := filepath.Dir(move.dest) os.Mkdir(dir, 0755) if err := os.Rename(move.src, move.dest); err != nil { fmt.Println(err) } } func main() { for _, path := range os.Args[1:] { info, err := os.Stat(path) if err != nil || !info.IsDir() { continue } fmt.Println("Processing folder") fmt.Println(path) files := fileop.WalkFolder(path, fileop.File) shas := pipe.Proc(files, 4, Calculate) cmds := pipe.Proc(shas, 1, Move(path)) pipe.TailProc(cmds, 4, Apply) fmt.Println("Deleting empty folders") files = fileop.WalkFolder(path, fileop.Folder) pipe.TailProc(files, 2, Delete) } }