commit 9499a4fe3604cddacf333786e7a8bb6017cc364f Author: JustAnyone Date: Sat Apr 18 01:39:43 2026 +0300 Initial commit diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7c88878 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module fix-mime-types + +go 1.22.3 + +require ( + github.com/gabriel-vasile/mimetype v1.4.4 + github.com/pelletier/go-toml/v2 v2.2.3 + golang.org/x/net v0.25.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4ee8384 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..7bd0b73 --- /dev/null +++ b/main.go @@ -0,0 +1,126 @@ +package main + +import ( + "errors" + "fmt" + "io" + "io/fs" + "log" + "os" + "path" + "path/filepath" + "strings" + + "github.com/gabriel-vasile/mimetype" + "github.com/pelletier/go-toml/v2" +) + +type Config struct { + Paths []string +} + +func loadConfiguration() (*Config, error) { + dir, err := os.UserConfigDir() + if err != nil { + return nil, err + } + + configFilePath := path.Join(dir, "justanyone", "fix-mime-types", "config.toml") + _, err = os.Stat(configFilePath) + if err != nil { + // If it's an error that is not for file not existing, send it upwards + if !errors.Is(err, os.ErrNotExist) { + return nil, err + } + + // Otherwise, create the parent directories + if err := os.MkdirAll(filepath.Dir(configFilePath), 0770); err != nil { + return nil, err + } + + // Marshal a default object + bytes, _ := toml.Marshal(&Config{Paths: []string{}}) + + file, err := os.Create(configFilePath) + if err != nil { + return nil, err + } + defer file.Close() + file.Write(bytes) + } + + file, err := os.Open(configFilePath) + if err != nil { + return nil, err + } + + bytes, err := io.ReadAll(file) + if err != nil { + return nil, err + } + + var config Config + err = toml.Unmarshal(bytes, &config) + if err != nil { + return nil, err + } + return &config, nil +} + +func main() { + config, err := loadConfiguration() + if err != nil { + log.Fatal("Failed to load configuration:", err) + } + + if len(config.Paths) == 0 { + fmt.Println("Warning: you have no configured directory paths") + } + + for _, directory := range config.Paths { + fixExtensionsInDirectory(directory) + } +} + +func shouldEntryBeChecked(entry fs.DirEntry) bool { + //fmt.Println(filepath.Ext(entry.Name())) + // If it's a file + return (entry.Type().IsRegular() && + // If it ends with .jpeg or .jpg + (strings.HasSuffix(entry.Name(), ".jpeg") || + strings.HasSuffix(entry.Name(), ".jpg"))) +} + +func getFileMimeType(pathToFile string) *mimetype.MIME { + mimeType, err := mimetype.DetectFile(pathToFile) + if err != nil { + panic(err) + } + return mimeType +} + +func changeFileExtension(originalPath string, newExtension string) { + oldExt := filepath.Ext(originalPath) + newPath := originalPath[0:len(originalPath)-len(oldExt)] + newExtension + os.Rename(originalPath, newPath) +} + +func fixExtensionsInDirectory(directory string) { + entries, err := os.ReadDir(directory) + if err != nil { + fmt.Println(err) + return + } + + for _, v := range entries { + if shouldEntryBeChecked(v) { + path := filepath.Join(directory, v.Name()) + if getFileMimeType(path).String() == "image/png" { + fmt.Println("File at", path, "was detected as png with wrong extension") + changeFileExtension(path, ".png") + } + } else if v.IsDir() { + fixExtensionsInDirectory(path.Join(directory, v.Name())) + } + } +}