github.com/levb/mattermost-server@v5.3.1+incompatible/utils/file_backend_local.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package utils
     5  
     6  import (
     7  	"bytes"
     8  	"io"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/mattermost/mattermost-server/mlog"
    15  	"github.com/mattermost/mattermost-server/model"
    16  )
    17  
    18  const (
    19  	TEST_FILE_PATH = "/testfile"
    20  )
    21  
    22  type LocalFileBackend struct {
    23  	directory string
    24  }
    25  
    26  func (b *LocalFileBackend) TestConnection() *model.AppError {
    27  	f := bytes.NewReader([]byte("testingwrite"))
    28  	if _, err := writeFileLocally(f, filepath.Join(b.directory, TEST_FILE_PATH)); err != nil {
    29  		return model.NewAppError("TestFileConnection", "api.file.test_connection.local.connection.app_error", nil, err.Error(), http.StatusInternalServerError)
    30  	}
    31  	os.Remove(filepath.Join(b.directory, TEST_FILE_PATH))
    32  	mlog.Info("Able to write files to local storage.")
    33  	return nil
    34  }
    35  
    36  func (b *LocalFileBackend) Reader(path string) (io.ReadCloser, *model.AppError) {
    37  	if f, err := os.Open(filepath.Join(b.directory, path)); err != nil {
    38  		return nil, model.NewAppError("Reader", "api.file.reader.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError)
    39  	} else {
    40  		return f, nil
    41  	}
    42  }
    43  
    44  func (b *LocalFileBackend) ReadFile(path string) ([]byte, *model.AppError) {
    45  	if f, err := ioutil.ReadFile(filepath.Join(b.directory, path)); err != nil {
    46  		return nil, model.NewAppError("ReadFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError)
    47  	} else {
    48  		return f, nil
    49  	}
    50  }
    51  
    52  func (b *LocalFileBackend) FileExists(path string) (bool, *model.AppError) {
    53  	_, err := os.Stat(filepath.Join(b.directory, path))
    54  
    55  	if os.IsNotExist(err) {
    56  		return false, nil
    57  	} else if err == nil {
    58  		return true, nil
    59  	}
    60  
    61  	return false, model.NewAppError("ReadFile", "api.file.file_exists.exists_local.app_error", nil, err.Error(), http.StatusInternalServerError)
    62  }
    63  
    64  func (b *LocalFileBackend) CopyFile(oldPath, newPath string) *model.AppError {
    65  	if err := CopyFile(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil {
    66  		return model.NewAppError("copyFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError)
    67  	}
    68  	return nil
    69  }
    70  
    71  func (b *LocalFileBackend) MoveFile(oldPath, newPath string) *model.AppError {
    72  	if err := os.MkdirAll(filepath.Dir(filepath.Join(b.directory, newPath)), 0774); err != nil {
    73  		return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError)
    74  	}
    75  
    76  	if err := os.Rename(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil {
    77  		return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError)
    78  	}
    79  
    80  	return nil
    81  }
    82  
    83  func (b *LocalFileBackend) WriteFile(fr io.Reader, path string) (int64, *model.AppError) {
    84  	return writeFileLocally(fr, filepath.Join(b.directory, path))
    85  }
    86  
    87  func writeFileLocally(fr io.Reader, path string) (int64, *model.AppError) {
    88  	if err := os.MkdirAll(filepath.Dir(path), 0774); err != nil {
    89  		directory, _ := filepath.Abs(filepath.Dir(path))
    90  		return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.create_dir.app_error", nil, "directory="+directory+", err="+err.Error(), http.StatusInternalServerError)
    91  	}
    92  	fw, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
    93  	if err != nil {
    94  		return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError)
    95  	}
    96  	defer fw.Close()
    97  	written, err := io.Copy(fw, fr)
    98  	if err != nil {
    99  		return written, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError)
   100  	}
   101  	return written, nil
   102  }
   103  
   104  func (b *LocalFileBackend) RemoveFile(path string) *model.AppError {
   105  	if err := os.Remove(filepath.Join(b.directory, path)); err != nil {
   106  		return model.NewAppError("RemoveFile", "utils.file.remove_file.local.app_error", nil, err.Error(), http.StatusInternalServerError)
   107  	}
   108  	return nil
   109  }
   110  
   111  func (b *LocalFileBackend) ListDirectory(path string) (*[]string, *model.AppError) {
   112  	var paths []string
   113  	if fileInfos, err := ioutil.ReadDir(filepath.Join(b.directory, path)); err != nil {
   114  		return nil, model.NewAppError("ListDirectory", "utils.file.list_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError)
   115  	} else {
   116  		for _, fileInfo := range fileInfos {
   117  			if fileInfo.IsDir() {
   118  				paths = append(paths, filepath.Join(path, fileInfo.Name()))
   119  			}
   120  		}
   121  	}
   122  	return &paths, nil
   123  }
   124  
   125  func (b *LocalFileBackend) RemoveDirectory(path string) *model.AppError {
   126  	if err := os.RemoveAll(filepath.Join(b.directory, path)); err != nil {
   127  		return model.NewAppError("RemoveDirectory", "utils.file.remove_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError)
   128  	}
   129  	return nil
   130  }