>백엔드 개발 >Golang >다운로드 폴더의 파일 자체 구성(자동)

다운로드 폴더의 파일 자체 구성(자동)

Barbara Streisand
Barbara Streisand원래의
2024-11-29 13:29:14124검색

Self-organize files in the downloads folder (automatically)

다운로드 폴더를 모니터링하고 해당 파일을 파일 유형에 맞는 하위 폴더에 정리하는 프로젝트를 많이 보셨을 것입니다.
그 중 하나가 더 있습니다! 하지만 매번 실행할 필요는 없으며 새 파일이 다운로드될 때 폴더를 적극적으로 모니터링하므로 아무것도 할 필요가 없습니다. 새 파일이 이동할 때마다 알림도 표시됩니다!

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)
}

#Go가 설치되어 있지 않나요? 소스 코드에서 실행 파일을 실행하기만 하면 됩니다!
저장소: https://github.com/costa86/folder-watcher

시간 내서 읽어주셔서 감사합니다!

팔로우:
링크드인 | Dev.to | 커피 사주세요 | GitHub

위 내용은 다운로드 폴더의 파일 자체 구성(자동)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.