Home > Backend Development > Golang > Self-organize files in the downloads folder (automatically)

Self-organize files in the downloads folder (automatically)

Barbara Streisand
Release: 2024-11-29 13:29:14
Original
127 people have browsed it

Self-organize files in the downloads folder (automatically)

I guess you've probably seen many projects that monitor the downloads folder and organizes the files there into a sub folder matching the file type.
This is one more of them! But you don't have to run it every now and them...it actively monitors the folder as new files are downloaded, so you don't have to do anything ?. It even shows a notification whenever a new file is moved!

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "log"
    "os"
    "path/filepath"
    "time"

    "github.com/fsnotify/fsnotify"
    "github.com/gen2brain/beeep"
)

func alert(title, message string) {
    err := beeep.Alert(title, message, "warn.png")
    if err != nil {
        panic(err)
    }
}

func move(filename, baseFolder, jsonFile string) {
    time.Sleep(2 * time.Second)
    extMap := getExtensionMap(jsonFile)
    folders := getFolderNames(extMap)
    if isFolder(filename, folders) {
        return
    }

    folder := getFolderName(extMap, filepath.Ext(filename))
    createFolder(baseFolder, folder, folders)
    src := fmt.Sprintf("%s/%s", baseFolder, filename)
    dest := fmt.Sprintf("%s/%s/%s", baseFolder, folder, filename)
    os.Rename(src, dest)
    alert(fmt.Sprintf("New file to: %s", folder), fmt.Sprintf("Dest: %s", dest))
}

func startWatching(baseFolder, jsonFile string) {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    go func() {
        for {
            select {
            case event, ok := <-watcher.Events:
                if !ok {
                    return
                }

                if event.Has(fsnotify.Create) {
                    filename := filepath.Base(event.Name)
                    move(filename, baseFolder, jsonFile)
                }

            case err, ok := <-watcher.Errors:
                if !ok {
                    return
                }
                fmt.Println("error:", err)
            }
        }
    }()
    err = watcher.Add(baseFolder)
    if err != nil {
        log.Fatal(err)
    }
    <-make(chan struct{})
}

func createFolder(baseFolder, name string, folders []string) {
    for _, v := range folders {
        if name == v {
            newFolder := fmt.Sprintf("%s/%s", baseFolder, v)
            if _, err := os.Stat(newFolder); os.IsNotExist(err) {
                os.Mkdir(newFolder, 0755)
                fmt.Printf("Folder created: %s", newFolder)
            }
        }
    }
}

func isFolder(name string, folders []string) bool {
    for _, v := range folders {
        if name == v {
            return true
        }
    }
    return false
}

func getExtensionMap(jsonFile string) map[string][]string {
    file, err := os.Open(jsonFile)
    if err != nil {
        fmt.Println("Error opening file:", err)
        os.Exit(1)
    }
    defer file.Close()

    data, err := io.ReadAll(file)
    if err != nil {
        fmt.Println("Error reading file:", err)
        os.Exit(1)
    }
    var extensionMap map[string][]string
    err = json.Unmarshal(data, &extensionMap)
    if err != nil {
        fmt.Println("Error unmarshalling JSON:", err)
        os.Exit(1)
    }
    return extensionMap

}

func getFolderName(extensionMap map[string][]string, extension string) string {
    for i := range extensionMap {
        for _, v := range extensionMap[i] {
            if v == extension {
                return i
            }
        }
    }
    return "other"
}

func getFolderNames(extensionMap map[string][]string) []string {
    folders := make([]string, 0, len(extensionMap))
    for folder := range extensionMap {
        folders = append(folders, folder)
    }
    return folders

}

func main() {

    if len(os.Args) != 3 {
        fmt.Println("Folder or Map file is missing")
        os.Exit(1)
    }

    dir := os.Args[1]
    mapFile := os.Args[2]

    info, err := os.Stat(dir)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        os.Exit(1)
    }

    if !info.IsDir() {
        fmt.Printf("%s is not a directory\n", dir)
        os.Exit(1)
    }
    startWatching(dir, mapFile)
}
Copy after login

Don't have #Go installed? Just run the executable in the source code!
Repo: https://github.com/costa86/folder-watcher

Thanks for the time reading this!

Follow me:
LinkedIn | Dev.to | Buy me a coffee | GitHub

The above is the detailed content of Self-organize files in the downloads folder (automatically). For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template