filemdl.go 11 KiB
Newer Older
Ajit Jagtap's avatar
Ajit Jagtap committed
package filemdl

Roshan Patil's avatar
Roshan Patil committed
import (
	"errors"
Roshan Patil's avatar
Roshan Patil committed
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"

	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
)

var (
	backupPath = ""
	dbPath     = ""
)

Roshan Patil's avatar
Roshan Patil committed
// TODO: Symbolic link evelution for this package not supported in windows .symlink file

// SetBackPath set backup folder path
func SetBackPath(folderPath, dbFolderPath string) error {
	if folderPath == "" || dbFolderPath == "" {
		return errors.New("Backup folder path and DB Path must not be empty")
	}
	bFolder, bFile := filepath.Split(folderPath)
	if bFile != "" {
		return errors.New("Backup Path must be folder or you forget to provide slash at the end")
	}
	dbFolder, dbFile := filepath.Split(dbFolderPath)
	if dbFile != "" {
		return errors.New("DB Path must be folder or you forget to provide slash at the end")
	}
	backupPath = bFolder
	dbPath = dbFolder
	return nil
}

// createFileBackup createfile back in backup folder
func createFileBackup(filePath string) error {
	if backupPath == "" || dbPath == "" {
		loggermdl.LogError("Backup folder path not set")
		return errors.New("Backup folder path not set")
	}
	backupFilePath := backupPath + strings.TrimPrefix(filePath, dbPath)
	_, err := CopyFile(filePath, backupFilePath, true)
	if errormdl.CheckErr(err) != nil {
		return errormdl.CheckErr(err)
	}
	return nil
}

Roshan Patil's avatar
Roshan Patil committed
//FileHelperServiceObject FileHelperServiceObject must be created while calling FileSearh function
type FileHelperServiceObject struct {
	searchResult   []string
	searchFileName string
}
Ajit Jagtap's avatar
Ajit Jagtap committed

// ReadFile reads contents from provided file path and retry when timeout occure
Ajit Jagtap's avatar
Ajit Jagtap committed
func ReadFile(filePath string) ([]byte, error) {
	path, linkErr := os.Readlink(filePath)
	if errormdl.CheckErr1(linkErr) == nil {
		filePath = path
	}
	ba, err := ioutil.ReadFile(filePath)
Roshan Patil's avatar
Roshan Patil committed
	if errormdl.CheckErr(err) != nil {
		if errormdl.CheckErr(err).Error() == "i/o timeout" {
			return ioutil.ReadFile(filePath)
		}
		return nil, errormdl.CheckErr(err)
Roshan Patil's avatar
Roshan Patil committed
}

//createFile creates a new file
func createFile(filePath string) (*os.File, error) {
	// function is usable for file module only. Required for zip module
Roshan Patil's avatar
Roshan Patil committed
	return os.Create(filePath)
}

func createRecursiveDirectoryForFile(filePath string) error {
	dir, _ := filepath.Split(filePath)
Roshan Patil's avatar
Roshan Patil committed
	createError := CreateDirectoryRecursive(dir)
	if errormdl.CheckErr(createError) != nil {
		loggermdl.LogError(createError)
		return errormdl.CheckErr(createError)
Roshan Patil's avatar
Roshan Patil committed
	}
	return nil
}

// WriteFile writes provided  bytes to file
func WriteFile(filePath string, data []byte, makeDir bool, createBackup bool) error {
	path, linkErr := os.Readlink(filePath)
	if errormdl.CheckErr1(linkErr) == nil {
		filePath = path
	}
Roshan Patil's avatar
Roshan Patil committed
	if makeDir {
		createError := createRecursiveDirectoryForFile(filePath)
		if errormdl.CheckErr(createError) != nil {
			loggermdl.LogError(createError)
			return errormdl.CheckErr(createError)
Roshan Patil's avatar
Roshan Patil committed
		}
	}
	if createBackup {
		backupErr := createFileBackup(filePath)
		if backupErr != nil {
			loggermdl.LogError(backupErr)
		}
	}
Roshan Patil's avatar
Roshan Patil committed
	return ioutil.WriteFile(filePath, data, 0644)
}

//AppendFile appends provided data/text to file
Roshan Patil's avatar
Roshan Patil committed
func AppendFile(filename string, text string) (int, error) {
	path, linkErr := os.Readlink(filename)
	if errormdl.CheckErr1(linkErr) == nil {
		filename = path
	}
Roshan Patil's avatar
Roshan Patil committed
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
	if errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
		return 0, errormdl.CheckErr(err)
Roshan Patil's avatar
Roshan Patil committed
	}

	defer f.Close()

	return f.WriteString(text)
}

//DeleteFile deletes provided file path
func DeleteFile(filePath string) error {
	path, linkErr := os.Readlink(filePath)
	if errormdl.CheckErr1(linkErr) == nil {
		filePath = path
	}
	err := os.Remove(filePath)
	if errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
		return errormdl.CheckErr(err)
	}
	return nil
Roshan Patil's avatar
Roshan Patil committed
}

// RenameFile renames/moves file from old path to new path
func RenameFile(oldFilePath, newFilePath string) error {
	return os.Rename(oldFilePath, newFilePath)
}

// CreateDirectory creates directory using provided path
func CreateDirectory(directoryPath string) error {
	return os.Mkdir(directoryPath, os.ModePerm)
}

// CreateDirectoryRecursive creates directory recursively using provided path
func CreateDirectoryRecursive(directoryPath string) error {
	return os.MkdirAll(directoryPath, os.ModePerm)
}

// DeleteDirectory creates directory using provided path
func DeleteDirectory(directoryPath string) error {
	return os.RemoveAll(directoryPath)
}

//ListDirectory returns list of all available components of directory
func ListDirectory(directoryPath string) ([]os.FileInfo, error) {
	return ioutil.ReadDir(directoryPath)
}

//MoveDirectory MoveDirectory
func MoveDirectory(source, destination string) error {
	return os.Rename(source, destination)
}

//MoveFile MoveFile
func MoveFile(source, destination string) error {
	return os.Rename(source, destination)
}

// MoveFileToOtherHost MoveFileToOtherHost
func MoveFileToOtherHost(source, destination string) error {
	// Copy source file to destination
	_, copyError := CopyFile(source, destination, true)
	if errormdl.CheckErr(copyError) != nil {
		loggermdl.LogError(copyError)
		return errormdl.CheckErr(copyError)
Roshan Patil's avatar
Roshan Patil committed
	}
	// Delete source file
	deleteError := DeleteFile(source)
	if errormdl.CheckErr1(deleteError) != nil {
		loggermdl.LogError(deleteError)
		return errormdl.CheckErr1(deleteError)
Roshan Patil's avatar
Roshan Patil committed
	}
	return nil
}

//CopyFile CopyFile
func CopyFile(source, destination string, makeDir bool) (int64, error) {
	// return os.Rename(source, destination)
	path, linkErr := os.Readlink(source)
	if errormdl.CheckErr1(linkErr) == nil {
		source = path
	}
Roshan Patil's avatar
Roshan Patil committed
	in, openError := os.Open(source)
	defer in.Close()
	if errormdl.CheckErr(openError) != nil {
		loggermdl.LogError(openError)
		return 0, errormdl.CheckErr(openError)
Roshan Patil's avatar
Roshan Patil committed
	}
	if makeDir {
		createError := createRecursiveDirectoryForFile(destination)
		if errormdl.CheckErr1(createError) != nil {
			loggermdl.LogError(createError)
			return 0, errormdl.CheckErr1(createError)
Roshan Patil's avatar
Roshan Patil committed
		}
	}
	out, createError := os.Create(destination)
	defer out.Close()
	if errormdl.CheckErr2(createError) != nil {
		loggermdl.LogError(createError)
		return 0, errormdl.CheckErr2(createError)
Roshan Patil's avatar
Roshan Patil committed
	}
	n, copyError := io.Copy(out, in)
	if errormdl.CheckErr3(copyError) != nil {
		loggermdl.LogError(copyError)
		return 0, errormdl.CheckErr3(copyError)
Roshan Patil's avatar
Roshan Patil committed
	}
	return n, nil
}

//CopyDir makes copy of source directory to the destination directory
func CopyDir(source string, dest string) (err error) {
	path, linkErr := os.Readlink(source)
	if errormdl.CheckErr2(linkErr) == nil {
		source = path
	}
Roshan Patil's avatar
Roshan Patil committed
	// get properties of source dir
	sourceinfo, err := os.Stat(source)
	if errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
		return errormdl.CheckErr(err)
Roshan Patil's avatar
Roshan Patil committed
	}
	// create dest dir

	err = os.MkdirAll(dest, sourceinfo.Mode())
	if errormdl.CheckErr1(err) != nil {
		loggermdl.LogError(err)
		return errormdl.CheckErr1(err)
Roshan Patil's avatar
Roshan Patil committed
	}
	directory, _ := os.Open(source)
	defer directory.Close()
Roshan Patil's avatar
Roshan Patil committed
	objects, err := directory.Readdir(-1)

	for _, obj := range objects {

		sourcefilepointer := source + "/" + obj.Name()

		destinationfilepointer := dest + "/" + obj.Name()

		if obj.IsDir() {
			// create sub-directories - recursively
			err = CopyDir(sourcefilepointer, destinationfilepointer)
			if errormdl.CheckErr2(err) != nil {
				loggermdl.LogError(err)
Roshan Patil's avatar
Roshan Patil committed
			}
		} else {
			// perform copy
			_, err = CopyFile(sourcefilepointer, destinationfilepointer, true)
			if errormdl.CheckErr2(err) != nil {
				loggermdl.LogError(err)
Roshan Patil's avatar
Roshan Patil committed
			}
		}

	}
	return
}

//ReplaceFile ReplaceFile
func ReplaceFile(data []byte, destination string, createBackup bool) error {
	path, linkErr := os.Readlink(destination)
	if errormdl.CheckErr(linkErr) == nil {
		destination = path
	}
	return WriteFile(destination, data, false, createBackup)
Roshan Patil's avatar
Roshan Patil committed
}

//TruncateFile TruncateFile
func TruncateFile(path string, size int64) error {
	tmp, linkErr := os.Readlink(path)
	if errormdl.CheckErr(linkErr) == nil {
		path = tmp
	}
Roshan Patil's avatar
Roshan Patil committed
	return os.Truncate(path, size)
}

//SeekFile SeekFile
// func SeekFile(path string, offset int64) error {
// 	file, err := os.OpenFile(path, os.O_RDWR, 0600)
// 	if err != nil {
// 		return err
// 	}

// 	defer file.Close()

// 	_, err = file.Seek(offset, 0)

// 	return err
// }

//FileInfo FileInfo
func FileInfo(path string) (os.FileInfo, error) {
	tmp, linkErr := os.Readlink(path)
	if errormdl.CheckErr(linkErr) == nil {
		path = tmp
	}
Roshan Patil's avatar
Roshan Patil committed
	return os.Stat(path)
}

//FileSearch FileSearch
func (fileHelperServiceObject *FileHelperServiceObject) FileSearch(fileName, path string) ([]string, error) {
	fileHelperServiceObject.searchResult = []string{}
	fileHelperServiceObject.searchFileName = fileName
	searchDirectory, err := os.Open(path)

	if errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
		return fileHelperServiceObject.searchResult, errormdl.CheckErr(err)
Roshan Patil's avatar
Roshan Patil committed
	}
	defer searchDirectory.Close()

	testFileInfo, _ := searchDirectory.Stat()
	if !testFileInfo.IsDir() {
		return fileHelperServiceObject.searchResult, err
	}

	err = filepath.Walk(path, fileHelperServiceObject.findFile)
	if errormdl.CheckErr1(err) != nil {
		loggermdl.LogError(err)
		return fileHelperServiceObject.searchResult, errormdl.CheckErr1(err)
Roshan Patil's avatar
Roshan Patil committed
	}
	return fileHelperServiceObject.searchResult, nil

}

func (fileHelperServiceObject *FileHelperServiceObject) findFile(path string, fileInfo os.FileInfo, err error) error {

	if errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
		return errormdl.CheckErr(err)
Roshan Patil's avatar
Roshan Patil committed
	}

	// get absolute path of the folder that we are searching
	absolute, err := filepath.Abs(path)
	if errormdl.CheckErr1(err) != nil {
		loggermdl.LogError(err)
		return errormdl.CheckErr1(err)
Roshan Patil's avatar
Roshan Patil committed
	}

	if fileInfo.IsDir() {
		testDir, err := os.Open(absolute)
		if errormdl.CheckErr2(err) != nil {
			loggermdl.LogError(err)
			return errormdl.CheckErr2(err)
Roshan Patil's avatar
Roshan Patil committed
		}
		testDir.Close()
		return nil
	}

	matched, err := filepath.Match(fileHelperServiceObject.searchFileName, fileInfo.Name())
	if errormdl.CheckErr3(err) != nil {
		loggermdl.LogError(err)
		return errormdl.CheckErr3(err)
Roshan Patil's avatar
Roshan Patil committed
	}
	if matched {
		add := absolute
		fileHelperServiceObject.searchResult = append(fileHelperServiceObject.searchResult, add)
	}

	return nil
}

//FileAvailabilityCheck checks whether file is available at given location
func FileAvailabilityCheck(filePath string) bool {
	tmp, linkErr := os.Readlink(filePath)
	if errormdl.CheckErr(linkErr) == nil {
		filePath = tmp
	}
Roshan Patil's avatar
Roshan Patil committed
	fileInfo, err := os.Stat(filePath)
	if fileInfo == nil && errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
Roshan Patil's avatar
Roshan Patil committed
		return false
	}
	return true
}

// CleanPath clean path
func CleanPath(path string) string {
	path = strings.Replace(path, "\n", "\\n", -1)
	path = strings.Replace(path, "\t", "\\t", -1)
	path = strings.Replace(path, "\r", "\\r", -1)
	path = strings.Replace(path, "\b", "\\b", -1)
	path = strings.Replace(path, "\a", "\\b", -1)
	path = strings.Replace(path, "\v", "\\b", -1)
	//path = strings.Replace(path, '\', '/', -1)

	normalizedPath := filepath.Clean(path)
	normalizedPath = filepath.ToSlash(normalizedPath)

	if strings.HasSuffix(path, string(filepath.Separator)) || strings.HasSuffix(path, "/") {
		normalizedPath = normalizedPath + "/"
	}

	return normalizedPath
}