Created
July 19, 2023 09:09
-
-
Save NathBabs/2fd500eb82f93f90bc981f0033d20ad8 to your computer and use it in GitHub Desktop.
Cleanup a folder by arranging files into their appropraite folders. Run by passing in the path to the folder it should clean e.g ` go run cleanup.go ~/Downloads/test`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"path/filepath" | |
) | |
// crate a map of file extensions to folders | |
// folderMap := make(map[string]string) | |
var folderMap = map[string]string{ | |
".txt": "TextFiles", | |
".doc": "Documents", | |
".docx": "Documents", | |
".pdf": "Documents", | |
".zip": "Compressed", | |
".gz": "Compressed", | |
".jpg": "Pictures", | |
".jpeg": "Pictures", | |
".png": "Pictures", | |
".mp4": "Videos", | |
".mkv": "Videos", | |
".mov": "Videos", | |
".mp3": "Music", | |
".app": "Apps", | |
".dmg": "Apps", | |
".pkg": "Apps", | |
".srt": "Videos", | |
} | |
// create slice to hold file extensions that could not be handled | |
var unhandledExtensions []string | |
// create a function that takes in a folder path from the command line | |
// verify it's a folder | |
// go run cleanup.go ~/Users/josh/Desktop/test | |
func cleanup(path string) (bool, error) { | |
_, err := IsDirectory(path) | |
if err != nil { | |
fmt.Printf("Path at: %v is not a directory please input a path to a file ", path) | |
return false, err | |
} | |
// read the directory | |
dir, err := os.Open(path) | |
if err != nil { | |
fmt.Println("Error opening directory:", err) | |
} | |
// read the directory | |
files, err := dir.Readdir(-1) | |
if err != nil { | |
fmt.Println("Unable to read directory:", err) | |
} | |
for _, file := range files { | |
// get file extension of a file | |
fileExt := filepath.Ext(file.Name()) | |
// check if file is also a directory | |
if (fileExt == "" || fileExt == ".DS_Store") || file.IsDir() { | |
fmt.Println("File has no extension or is a directory") | |
continue | |
} | |
// get file extension from map and create appropariate folder | |
folder, found := folderMap[fileExt] | |
if !found { | |
msg := fmt.Sprintf("Sorry can not handle this file extension: %v", fileExt) | |
//fmt.Fprintf(os.Stderr, "Sorry can not handle this file extension: %v", fileExt) //rintf("Sorry can not handle this file extension: %v", fileExt) | |
fmt.Println(msg) | |
// after printing the error, continue to the next file | |
// add file extension to unhandledExtensions | |
unhandledExtensions = append(unhandledExtensions, fileExt) | |
continue | |
} | |
// os.Mkdir(folderPath, os.ModePerm) | |
// check if Folder exists in directory, if not create | |
folderPath := filepath.Join(path, folder) | |
fmt.Println("folderPath is :", folderPath) | |
// check if folder exists, if not create | |
// then move file to folder | |
_, err = os.Stat(folderPath) | |
if err != nil { | |
if errDir := os.Mkdir(folderPath, os.ModePerm); errDir != nil { | |
// stop loop and stop program | |
fmt.Println("Error creating folder:", err) | |
return false, errDir | |
} | |
} | |
fmt.Println("Folder now exists") | |
// move the file to the newly created folder | |
oldFilePath := filepath.Join(path, file.Name()) | |
newFilePath := filepath.Join(folderPath, file.Name()) | |
// print to the terminal, "moving {file.Name} to {newFolderPath}" | |
fmt.Printf("Moving %v to %v\n......", file.Name(), folderPath) | |
// change permission of file, so that it can be moved | |
err = os.Chmod(oldFilePath, 0777) | |
if err != nil { | |
fmt.Println("Error changing file permission:", err) | |
os.Exit(1) | |
} | |
err = os.Rename(oldFilePath, newFilePath) | |
if err != nil { | |
fmt.Println("Error moving file:", err) | |
os.Exit(1) | |
} | |
// print to the terminal, "done moving to {newFolderPath}" | |
fmt.Println("done moving to", folderPath) | |
} | |
// close the folder | |
defer dir.Close() | |
// print unhandledExtensions, if slice is not empty | |
if len(unhandledExtensions) > 0 { | |
fmt.Println("Could not handle these file extensions: ", unhandledExtensions) | |
} | |
return true, nil | |
} | |
func IsDirectory(path string) (bool, error) { | |
fileInfo, err := os.Stat(path) | |
if err != nil { | |
return false, err | |
} | |
return fileInfo.IsDir(), err | |
} | |
func main() { | |
// get the path from the user | |
path := os.Args[1] | |
// call the cleanup function with the path | |
_, err := cleanup(path) | |
if err != nil { | |
fmt.Println("Error:", err) | |
os.Exit(1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@lyusuf40 Regarding your first point, for a program that does one thing, it's better it doesn't do any recursive task. If it should be recursive, then I believe it should be specified by the user, so that can be an added option , and probably take in a flag via the command line to indicate that e.g
-r
, and I'll check for this flag in the code.Then for your second point, that's true I actually contemplated it. I could probably create a slice to hold the folders that couldn't be created and print it to the user after the process is done.