2019-05-06 23:18:10 +02:00
|
|
|
package util
|
2018-11-17 06:21:39 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/zip"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"os/user"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2018-11-17 06:56:43 +01:00
|
|
|
// Returns true if file exists
|
2018-11-17 06:21:39 +01:00
|
|
|
func Exists(filename string) bool {
|
|
|
|
info, err := os.Stat(filename)
|
|
|
|
|
|
|
|
return err == nil && !info.IsDir()
|
|
|
|
}
|
|
|
|
|
2019-06-20 01:11:03 +02:00
|
|
|
// Overwrite overwrites the file with data. Creates file if not present.
|
|
|
|
func Overwrite(fileName string, data []byte) bool {
|
|
|
|
f, err := os.Create(fileName)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = f.Write(data)
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
2018-11-17 06:56:43 +01:00
|
|
|
// Returns full path; ~ replaced with actual home directory
|
2018-11-17 06:21:39 +01:00
|
|
|
func ExpandedFilename(filename string) string {
|
|
|
|
if filename == "" {
|
2019-05-04 05:25:00 +02:00
|
|
|
return ""
|
2018-11-17 06:21:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(filename) > 2 && filename[:2] == "~/" {
|
2019-01-03 05:45:54 +01:00
|
|
|
if usr, err := user.Current(); err == nil {
|
|
|
|
filename = filepath.Join(usr.HomeDir, filename[2:])
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
}
|
|
|
|
|
2019-01-03 05:45:54 +01:00
|
|
|
result, err := filepath.Abs(filename)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2018-11-17 06:56:43 +01:00
|
|
|
// Extract Zip file in destination directory
|
2019-01-13 00:45:22 +01:00
|
|
|
func Unzip(src, dest string) (fileNames []string, err error) {
|
2018-11-17 06:21:39 +01:00
|
|
|
r, err := zip.OpenReader(src)
|
|
|
|
if err != nil {
|
|
|
|
return fileNames, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer r.Close()
|
|
|
|
|
|
|
|
for _, f := range r.File {
|
|
|
|
// Skip directories like __OSX
|
|
|
|
if strings.HasPrefix(f.Name, "__") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
fn, err := copyToFile(f, dest)
|
2018-11-17 06:21:39 +01:00
|
|
|
if err != nil {
|
|
|
|
return fileNames, err
|
|
|
|
}
|
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
fileNames = append(fileNames, fn)
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
return fileNames, nil
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
// copyToFile copies the zip file to destination
|
|
|
|
// if the zip file is a directory, a directory is created at the destination.
|
|
|
|
func copyToFile(f *zip.File, dest string) (fileName string, err error) {
|
|
|
|
rc, err := f.Open()
|
|
|
|
if err != nil {
|
|
|
|
return fileName, err
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
defer rc.Close()
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
// Store filename/path for returning and using later on
|
|
|
|
fileName = filepath.Join(dest, f.Name)
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
if f.FileInfo().IsDir() {
|
|
|
|
// Make Folder
|
|
|
|
return fileName, os.MkdirAll(fileName, os.ModePerm)
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
// Make File
|
|
|
|
var fdir string
|
|
|
|
if lastIndex := strings.LastIndex(fileName, string(os.PathSeparator)); lastIndex > -1 {
|
|
|
|
fdir = fileName[:lastIndex]
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
err = os.MkdirAll(fdir, os.ModePerm)
|
|
|
|
if err != nil {
|
|
|
|
return fileName, err
|
|
|
|
}
|
2018-11-17 06:21:39 +01:00
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
fd, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
|
|
|
if err != nil {
|
|
|
|
return fileName, err
|
2018-11-17 06:21:39 +01:00
|
|
|
}
|
|
|
|
|
2019-01-13 00:45:22 +01:00
|
|
|
defer fd.Close()
|
|
|
|
_, err = io.Copy(fd, rc)
|
|
|
|
if err != nil {
|
|
|
|
return fileName, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return fileName, nil
|
2018-11-17 06:21:39 +01:00
|
|
|
}
|
|
|
|
|
2018-11-17 06:56:43 +01:00
|
|
|
// Download a file from a URL
|
2019-01-13 00:45:22 +01:00
|
|
|
func Download(filepath string, url string) error {
|
2018-11-17 06:21:39 +01:00
|
|
|
os.MkdirAll("/tmp/photoprism", os.ModePerm)
|
|
|
|
|
|
|
|
// Create the file
|
|
|
|
out, err := os.Create(filepath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer out.Close()
|
|
|
|
|
|
|
|
// Get the data
|
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
// Check server response
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
return fmt.Errorf("bad status: %s", resp.Status)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Writer the body to file
|
|
|
|
_, err = io.Copy(out, resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2019-05-13 18:01:50 +02:00
|
|
|
|
|
|
|
func DirectoryIsEmpty(path string) bool {
|
|
|
|
f, err := os.Open(path)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
_, err = f.Readdirnames(1)
|
|
|
|
|
|
|
|
if err == io.EOF {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|