github.com/ashishbhate/mattermost-server@v5.11.1+incompatible/services/filesstore/localstore.go (about)

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