package main import ( "fmt" "io" "os" "path/filepath" "strings" ) var ( KEEP_SRT bool = false ) func scan_dir(dir string) ([]string, error) { var r []string = []string{} ls, err := os.ReadDir(dir) if err != nil { return nil, err } for _, elem := range ls { if elem.IsDir() { rs, err := scan_dir(filepath.Join(dir, elem.Name())) if err != nil { return nil, err } for _, e := range rs { r = append(r, filepath.Join(elem.Name(), e)) } } else { if strings.HasSuffix(elem.Name(), ".srt") { if !KEEP_SRT { continue } r = append(r, elem.Name()) continue } if strings.HasSuffix(elem.Name(), ".info") || strings.HasSuffix(elem.Name(), ".txt") { continue } r = append(r, elem.Name()) } } return r, nil } func is_empty(dir string) bool { ls, err := os.ReadDir(dir) if err != nil { return false } for _, elem := range ls { if elem.IsDir() { return is_empty(filepath.Join(dir, elem.Name())) } if strings.HasSuffix(elem.Name(), ".srt") { if !KEEP_SRT { continue } return false } if strings.HasSuffix(elem.Name(), ".info") || strings.HasSuffix(elem.Name(), ".txt") { continue } return false } return true } func scan_for_dirs(dir string) ([]string, error) { var r []string = []string{} ls, err := os.ReadDir(dir) if err != nil { return nil, err } for _, elem := range ls { if elem.IsDir() && is_empty(filepath.Join(dir, elem.Name())) { r = append(r, filepath.Join(dir, elem.Name())) } } return r, nil } func main() { var REMOVE bool = true // Keeps if len(os.Args) != 1 { for idx, arg := range os.Args { if idx == 0 { // Skip program name continue } switch strings.ToLower(arg) { case "srt": KEEP_SRT = true case "norm", "no-rm", "no-remove": REMOVE = false case "help", "h", "?": fmt.Println("--- Help ---") fmt.Println("undir will move 1 or more files from a directory, then delete the directory.") fmt.Println("") fmt.Println("Commands:") fmt.Println("") fmt.Println(" srt undir will move *.srt files") fmt.Println(" norm, no-rm, no-remove undir will NOT remove directories or files") fmt.Println(" help, h, ? Prints this help screen and exits (code 0, success)") fmt.Println("") fmt.Println("Example Usage:") fmt.Println("") fmt.Println("undir Standard run of undir, will move any file NOT *.info or *.srt") fmt.Println("undir srt Run undir but move *.srt files") fmt.Println("undir no-rm Run undir but do NOT remove directories or files, simply copy them") fmt.Println("undir srt norm Run undir but move *.srt files, also do NOT remove directories or files, simply copy them") fmt.Println("undir ? Prints this help screen and exits (code 0, success)") os.Exit(0) } } if KEEP_SRT { fmt.Println("Keeping .srt's") } if !REMOVE { fmt.Println("No Remove Mode") } } actions, err := scan_dir(".") if err != nil { fmt.Println("Err:", err) return } fmt.Println("Found:", len(actions)) for idx, a := range actions { fmt.Println(a) out, err := os.Create(filepath.Base(a)) if err != nil { fmt.Println("Err (Create out):", err) continue } in, err := os.Open(a) if err != nil { out.Close() fmt.Println("RM", filepath.Base(a)) err1 := os.Remove(filepath.Base(a)) if err1 != nil { fmt.Println("Err (Cleanup):", err1) } fmt.Println("Err (Open in):", err) continue } _, err = io.Copy(out, in) if err != nil { in.Close() out.Close() fmt.Println("RM", filepath.Base(a)) err1 := os.Remove(filepath.Base(a)) if err1 != nil { fmt.Println("Err (Cleanup):", err1) } fmt.Println("Err (Copy in -> out):", err) continue } if idx+1 < len(actions) { fmt.Println("End?") if REMOVE { fmt.Println("RM", filepath.Dir(a)) err = os.RemoveAll(filepath.Dir(a)) if err != nil { fmt.Println("Err (Remove):", err) } var can_clean bool = true for _, next := range actions[idx+1:] { if filepath.Dir(next) == filepath.Dir(a) { can_clean = false } } if can_clean { new_scan, err := scan_for_dirs(".") if err != nil { fmt.Println("Err (Rescan):", err) continue } if len(new_scan) != 0 { for _, elem := range new_scan { fmt.Println("RM", elem) err = os.RemoveAll(elem) if err != nil { fmt.Println("Err (Remove):", err) } } } } } continue } var can_clean bool = true for _, next := range actions[idx+1:] { if filepath.Dir(next) == filepath.Dir(a) { can_clean = false } } if can_clean && REMOVE { fmt.Println("RM", filepath.Dir(a)) err = os.RemoveAll(filepath.Dir(a)) if err != nil { fmt.Println("Err (Remove):", err) continue } new_scan, err := scan_for_dirs(".") if err != nil { fmt.Println("Err (Rescan):", err) continue } if len(new_scan) != 0 { for _, elem := range new_scan { fmt.Println("RM", elem) err = os.RemoveAll(elem) if err != nil { fmt.Println("Err (Remove):", err) } } } } } }