package storage import ( "errors" "io/fs" "os" "path/filepath" "github.com/sirupsen/logrus" ) type Storage interface { ListFiles() ([]string, error) ReadFile(filename string) ([]byte, error) WriteFile(filename string, content []byte) error DeleteFile(filename string) error FileExists(filename string) bool } type FileStorage struct { dataDir string logger *logrus.Logger } func NewFileStorage(dataDir string) (*FileStorage, error) { // Create data directory if it doesn't exist if err := os.MkdirAll(dataDir, 0755); err != nil { return nil, err } log := logrus.New() log.SetOutput(os.Stdout) log.SetFormatter(&logrus.TextFormatter{ ForceColors: true, FullTimestamp: true, }) log.SetLevel(logrus.InfoLevel) return &FileStorage{ dataDir: dataDir, logger: log, }, nil } func (s *FileStorage) ListFiles() ([]string, error) { files, err := os.ReadDir(s.dataDir) if err != nil { return nil, err } var markdownFiles []string for _, file := range files { if !file.IsDir() && filepath.Ext(file.Name()) == ".md" { markdownFiles = append(markdownFiles, file.Name()) } } return markdownFiles, nil } func (s *FileStorage) ReadFile(filename string) ([]byte, error) { if !s.FileExists(filename) { return nil, errors.New("file not found") } content, err := os.ReadFile(filepath.Join(s.dataDir, filename)) if err != nil { return nil, err } return content, nil } func (s *FileStorage) WriteFile(filename string, content []byte) error { // Ensure the file has .md extension if filepath.Ext(filename) != ".md" { filename += ".md" } filepath := filepath.Join(s.dataDir, filename) err := os.WriteFile(filepath, content, 0644) if err != nil { return err } s.logger.Infof("Saved file: %s", filename) return nil } func (s *FileStorage) DeleteFile(filename string) error { filepath := filepath.Join(s.dataDir, filename) err := os.Remove(filepath) if err != nil { if errors.Is(err, fs.ErrNotExist) { return errors.New("file not found") } return err } s.logger.Infof("Deleted file: %s", filename) return nil } func (s *FileStorage) FileExists(filename string) bool { filepath := filepath.Join(s.dataDir, filename) info, err := os.Stat(filepath) if err != nil { return false } return !info.IsDir() }