package pkg import ( "crypto/rand" "fmt" "os" "path/filepath" "time" ) type Dir struct { Path string PathCurrentDir string PathBackupDir string } // NewDir creates a new Dir instance. func NewDir(dir, nameCurrentDir string) *Dir { return &Dir{ Path: dir, PathCurrentDir: filepath.Join(dir, nameCurrentDir), PathBackupDir: filepath.Join(dir, nameCurrentDir+".bak"), } } // CreateRandomTmpDir creates a temporary directory in the specified directory with a random name. // The directory is created with permissions 0750. // If the directory already exists, an error is returned. // @return string - path to the temporary directory // @return error - an error if the directory could not be created func (d *Dir) CreateRandomTmpDir() (string, error) { tmpDir := filepath.Join(d.Path, time.Now().Format(time.RFC3339)+"_"+rand.Text()+".tmp") if _, err := os.Stat(tmpDir); err == nil { return "", fmt.Errorf("directory already exists: %s", tmpDir) } if err := os.MkdirAll(tmpDir, 0750); err != nil { return "", err } return tmpDir, nil } // ReplaceDirToCurrent replaces the current directory with a new directory. // If the new directory already exists, it is renamed to a backup directory. // If the backup directory already exists, it is removed. // @return error - an error if the directory could not be replaced func (d *Dir) ReplaceDirToCurrent(newDir string) error { if err := os.RemoveAll(d.PathBackupDir); err != nil { return err } if _, err := os.Stat(d.PathCurrentDir); err == nil { if err := os.Rename(d.PathCurrentDir, d.PathBackupDir); err != nil { return err } } if err := os.Rename(newDir, d.PathCurrentDir); err != nil { if _, statErr := os.Stat(d.PathBackupDir); statErr == nil { _ = os.Rename(d.PathBackupDir, d.PathCurrentDir) } return err } if err := os.RemoveAll(d.PathBackupDir); err != nil { return err } return nil } // MovingFiles moves all files from dirFrom to dirTo. // If dirTo does not exist, it is created. // @param dirFrom - path to the directory containing the files to move // @param dirTo - path to the directory where the files will be moved // @return error - an error if the files could not be moved func MovingFiles(dirFrom, dirTo string) error { if _, err := os.Stat(dirTo); err != nil { if err := os.MkdirAll(dirTo, 0750); err != nil { return err } } entries, err := os.ReadDir(dirFrom) if err != nil { return err } for _, entry := range entries { if entry.IsDir() { if err := MovingFiles(filepath.Join(dirFrom, entry.Name()), dirTo); err != nil { return err } continue } src := filepath.Join(dirFrom, entry.Name()) dst := filepath.Join(dirTo, entry.Name()) if err := os.Rename(src, dst); err != nil { return err } } return nil } // FindMMDBFile finds the .mmdb file in the specified directory. // @param dir - path to the directory to search // @return string - path to the .mmdb file // @return error - an error if the .mmdb file could not be found func FindMMDBFile(dir string) (string, error) { entries, err := os.ReadDir(dir) if err != nil { return "", err } for _, entry := range entries { if entry.IsDir() { continue } if filepath.Ext(entry.Name()) == ".mmdb" { return filepath.Join(dir, entry.Name()), nil } } return "", fmt.Errorf("no .mmdb file found in %s", dir) }