Backend: Move reusable packages to pkg/
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
fbea88bd74
commit
f8a45b14d9
85 changed files with 5244 additions and 5239 deletions
16
Makefile
16
Makefile
|
@ -83,23 +83,23 @@ acceptance-firefox:
|
|||
(cd frontend && npm run acceptance-firefox)
|
||||
test-go:
|
||||
$(info Running all Go unit tests...)
|
||||
$(GOTEST) -count=1 -tags=slow -timeout 20m ./internal/...
|
||||
$(GOTEST) -count=1 -tags=slow -timeout 20m ./pkg/... ./internal/...
|
||||
test-verbose:
|
||||
$(info Running all Go unit tests in verbose mode...)
|
||||
$(GOTEST) -tags=slow -timeout 20m -v ./internal/...
|
||||
$(GOTEST) -tags=slow -timeout 20m -v ./pkg/... ./internal/...
|
||||
test-short:
|
||||
$(info Running short Go unit tests in verbose mode...)
|
||||
$(GOTEST) -short -timeout 5m -v ./internal/...
|
||||
$(GOTEST) -short -timeout 5m -v ./pkg/... ./internal/...
|
||||
test-race:
|
||||
$(info Running all Go unit tests with race detection in verbose mode...)
|
||||
$(GOTEST) -tags=slow -race -timeout 60m -v ./internal/...
|
||||
$(GOTEST) -tags=slow -race -timeout 60m -v ./pkg/... ./internal/...
|
||||
test-codecov:
|
||||
$(info Running all Go unit tests with code coverage report for codecov...)
|
||||
go test -count=1 -tags=slow -timeout 30m -coverprofile=coverage.txt -covermode=atomic -v ./internal/...
|
||||
go test -count=1 -tags=slow -timeout 30m -coverprofile=coverage.txt -covermode=atomic -v ./pkg/... ./internal/...
|
||||
scripts/codecov.sh
|
||||
test-coverage:
|
||||
$(info Running all Go unit tests with code coverage report...)
|
||||
go test -count=1 -tags=slow -timeout 30m -coverprofile=coverage.txt -covermode=atomic -v ./internal/...
|
||||
go test -count=1 -tags=slow -timeout 30m -coverprofile=coverage.txt -covermode=atomic -v ./pkg/... ./internal/...
|
||||
go tool cover -html=coverage.txt -o coverage.html
|
||||
clean:
|
||||
rm -f $(BINARY_NAME)
|
||||
|
@ -131,8 +131,8 @@ lint-js:
|
|||
fmt-js:
|
||||
(cd frontend && npm run fmt)
|
||||
fmt-go:
|
||||
goimports -w internal cmd
|
||||
go fmt ./internal/... ./cmd/...
|
||||
goimports -w pkg internal cmd
|
||||
go fmt ./pkg/... ./internal/... ./cmd/...
|
||||
tidy:
|
||||
go mod tidy
|
||||
upgrade-js:
|
||||
|
|
|
@ -12,16 +12,16 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// GET /api/v1/albums
|
||||
|
@ -368,7 +368,7 @@ func DownloadAlbum(router *gin.RouterGroup, conf *config.Config) {
|
|||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
fileAlias := f.DownloadFileName()
|
||||
|
||||
if file.Exists(fileName) {
|
||||
if fs.FileExists(fileName) {
|
||||
if err := addFileToZip(zipWriter, fileName, fileAlias); err != nil {
|
||||
log.Error(err)
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": txt.UcFirst("failed to create zip file")})
|
||||
|
@ -387,7 +387,7 @@ func DownloadAlbum(router *gin.RouterGroup, conf *config.Config) {
|
|||
zipWriter.Close()
|
||||
newZipFile.Close()
|
||||
|
||||
if !file.Exists(zipFileName) {
|
||||
if !fs.FileExists(zipFileName) {
|
||||
log.Errorf("could not find zip file: %s", zipFileName)
|
||||
c.Data(404, "image/svg+xml", photoIconSvg)
|
||||
return
|
||||
|
@ -433,7 +433,7 @@ func AlbumThumbnail(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("could not find original for thumbnail: %s", fileName)
|
||||
c.Data(http.StatusNotFound, "image/svg+xml", photoIconSvg)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"path"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
@ -33,7 +33,7 @@ func GetDownload(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("could not find original: %s", fileHash)
|
||||
c.Data(404, "image/svg+xml", photoIconSvg)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package api
|
|||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/photoprism"
|
||||
)
|
||||
|
||||
|
@ -60,7 +60,7 @@ func StartImport(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
imp.Start(path)
|
||||
|
||||
if subPath != "" && path != conf.ImportPath() && file.IsEmpty(path) {
|
||||
if subPath != "" && path != conf.ImportPath() && fs.IsEmpty(path) {
|
||||
if err := os.Remove(path); err != nil {
|
||||
log.Errorf("import: could not deleted empty directory \"%s\": %s", path, err)
|
||||
} else {
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/nsfw"
|
||||
"github.com/photoprism/photoprism/internal/photoprism"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var ind *photoprism.Index
|
||||
|
|
|
@ -12,11 +12,11 @@ import (
|
|||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// GET /api/v1/labels
|
||||
|
@ -153,7 +153,7 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("could not find original for thumbnail: %s", fileName)
|
||||
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
@ -83,7 +83,7 @@ func GetPhotoDownload(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("could not find original: %s", c.Param("uuid"))
|
||||
c.Data(404, "image/svg+xml", photoIconSvg)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
)
|
||||
|
@ -40,7 +40,7 @@ func GetThumbnail(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("could not find original for thumbnail: %s", fileName)
|
||||
c.Data(http.StatusNotFound, "image/svg+xml", photoIconSvg)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/disintegration/imaging"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
|
@ -33,7 +33,7 @@ func GetPreview(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
previewFilename := fmt.Sprintf("%s/%s.jpg", thumbPath, t[6:8])
|
||||
|
||||
if file.Exists(previewFilename) {
|
||||
if fs.FileExists(previewFilename) {
|
||||
c.File(previewFilename)
|
||||
return
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func GetPreview(router *gin.RouterGroup, conf *config.Config) {
|
|||
for _, f := range p {
|
||||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("could not find original for thumbnail: %s", fileName)
|
||||
c.Data(http.StatusNotFound, "image/svg+xml", photoIconSvg)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/session"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// POST /api/v1/session
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// GET /api/v1/settings
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
|
|
@ -11,11 +11,11 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
@ -74,7 +74,7 @@ func CreateZip(router *gin.RouterGroup, conf *config.Config) {
|
|||
fileName := path.Join(conf.OriginalsPath(), f.FileName)
|
||||
fileAlias := f.DownloadFileName()
|
||||
|
||||
if file.Exists(fileName) {
|
||||
if fs.FileExists(fileName) {
|
||||
if err := addFileToZip(zipWriter, fileName, fileAlias); err != nil {
|
||||
log.Error(err)
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": txt.UcFirst("failed to create zip file")})
|
||||
|
@ -105,7 +105,7 @@ func DownloadZip(router *gin.RouterGroup, conf *config.Config) {
|
|||
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", zipBaseName))
|
||||
|
||||
if !file.Exists(zipFileName) {
|
||||
if !fs.FileExists(zipFileName) {
|
||||
log.Errorf("could not find zip file: %s", zipFileName)
|
||||
c.Data(404, "image/svg+xml", photoIconSvg)
|
||||
return
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,7 @@ func main() {
|
|||
|
||||
fileName := "rules.yml"
|
||||
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Panicf("tensorflow: label rules file not found in \"%s\"", filepath.Base(fileName))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package classify
|
|||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// Labels is list of MediaFile labels.
|
||||
|
|
|
@ -12,14 +12,14 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/sevlyar/go-daemon"
|
||||
)
|
||||
|
||||
var log = event.Log
|
||||
|
||||
func childAlreadyRunning(filePath string) (pid int, running bool) {
|
||||
if !file.Exists(filePath) {
|
||||
if !fs.FileExists(filePath) {
|
||||
return pid, false
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/server"
|
||||
"github.com/sevlyar/go-daemon"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -96,7 +96,7 @@ func startAction(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
if child != nil {
|
||||
if !file.Overwrite(conf.PIDFilename(), []byte(strconv.Itoa(child.Pid))) {
|
||||
if !fs.Overwrite(conf.PIDFilename(), []byte(strconv.Itoa(child.Pid))) {
|
||||
log.Fatalf("failed writing process id to \"%s\"", conf.PIDFilename())
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/colors"
|
||||
"github.com/photoprism/photoprism/pkg/colors"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// HTTP client / Web UI config values
|
||||
|
@ -118,8 +118,8 @@ func (c *Config) ClientConfig() ClientConfig {
|
|||
categories[i].Title = strings.Title(l.LabelName)
|
||||
}
|
||||
|
||||
jsHash := file.Hash(c.HttpStaticBuildPath() + "/app.js")
|
||||
cssHash := file.Hash(c.HttpStaticBuildPath() + "/app.css")
|
||||
jsHash := fs.Hash(c.HttpStaticBuildPath() + "/app.js")
|
||||
cssHash := fs.Hash(c.HttpStaticBuildPath() + "/app.css")
|
||||
|
||||
// Feature Flags
|
||||
var flags []string
|
||||
|
|
|
@ -3,7 +3,7 @@ package config
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -17,7 +17,7 @@ func TestNewConfig(t *testing.T) {
|
|||
|
||||
assert.IsType(t, new(Config), c)
|
||||
|
||||
assert.Equal(t, file.ExpandFilename("../../assets"), c.AssetsPath())
|
||||
assert.Equal(t, fs.ExpandFilename("../../assets"), c.AssetsPath())
|
||||
assert.False(t, c.Debug())
|
||||
assert.False(t, c.ReadOnly())
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
func findExecutable(configBin, defaultBin string) (result string) {
|
||||
|
@ -19,7 +19,7 @@ func findExecutable(configBin, defaultBin string) (result string) {
|
|||
result = path
|
||||
}
|
||||
|
||||
if !file.Exists(result) {
|
||||
if !fs.FileExists(result) {
|
||||
result = ""
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/urfave/cli"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
@ -88,7 +88,7 @@ func NewParams(ctx *cli.Context) *Params {
|
|||
c.Name = ctx.App.Name
|
||||
c.Copyright = ctx.App.Copyright
|
||||
c.Version = ctx.App.Version
|
||||
c.ConfigFile = file.ExpandFilename(ctx.GlobalString("config-file"))
|
||||
c.ConfigFile = fs.ExpandFilename(ctx.GlobalString("config-file"))
|
||||
|
||||
if err := c.SetValuesFromFile(c.ConfigFile); err != nil {
|
||||
log.Debug(err)
|
||||
|
@ -104,21 +104,21 @@ func NewParams(ctx *cli.Context) *Params {
|
|||
}
|
||||
|
||||
func (c *Params) expandFilenames() {
|
||||
c.ConfigPath = file.ExpandFilename(c.ConfigPath)
|
||||
c.ResourcesPath = file.ExpandFilename(c.ResourcesPath)
|
||||
c.AssetsPath = file.ExpandFilename(c.AssetsPath)
|
||||
c.CachePath = file.ExpandFilename(c.CachePath)
|
||||
c.OriginalsPath = file.ExpandFilename(c.OriginalsPath)
|
||||
c.ImportPath = file.ExpandFilename(c.ImportPath)
|
||||
c.ExportPath = file.ExpandFilename(c.ExportPath)
|
||||
c.SqlServerPath = file.ExpandFilename(c.SqlServerPath)
|
||||
c.PIDFilename = file.ExpandFilename(c.PIDFilename)
|
||||
c.LogFilename = file.ExpandFilename(c.LogFilename)
|
||||
c.ConfigPath = fs.ExpandFilename(c.ConfigPath)
|
||||
c.ResourcesPath = fs.ExpandFilename(c.ResourcesPath)
|
||||
c.AssetsPath = fs.ExpandFilename(c.AssetsPath)
|
||||
c.CachePath = fs.ExpandFilename(c.CachePath)
|
||||
c.OriginalsPath = fs.ExpandFilename(c.OriginalsPath)
|
||||
c.ImportPath = fs.ExpandFilename(c.ImportPath)
|
||||
c.ExportPath = fs.ExpandFilename(c.ExportPath)
|
||||
c.SqlServerPath = fs.ExpandFilename(c.SqlServerPath)
|
||||
c.PIDFilename = fs.ExpandFilename(c.PIDFilename)
|
||||
c.LogFilename = fs.ExpandFilename(c.LogFilename)
|
||||
}
|
||||
|
||||
// SetValuesFromFile uses a yaml config file to initiate the configuration entity.
|
||||
func (c *Params) SetValuesFromFile(fileName string) error {
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
return errors.New(fmt.Sprintf("config file not found: \"%s\"", fileName))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package config
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -17,7 +17,7 @@ func TestNewParams(t *testing.T) {
|
|||
|
||||
assert.IsType(t, new(Params), c)
|
||||
|
||||
assert.Equal(t, file.ExpandFilename("../../assets"), c.AssetsPath)
|
||||
assert.Equal(t, fs.ExpandFilename("../../assets"), c.AssetsPath)
|
||||
assert.False(t, c.Debug)
|
||||
assert.False(t, c.ReadOnly)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
|
@ -20,7 +20,7 @@ func NewSettings() *Settings {
|
|||
|
||||
// SetValuesFromFile uses a yaml config file to initiate the configuration entity.
|
||||
func (s *Settings) SetValuesFromFile(fileName string) error {
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
return fmt.Errorf("settings file not found: \"%s\"", fileName)
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ func (s *Settings) SetValuesFromFile(fileName string) error {
|
|||
|
||||
// WriteValuesToFile uses a yaml config file to initiate the configuration entity.
|
||||
func (s *Settings) WriteValuesToFile(fileName string) error {
|
||||
if !file.Exists(fileName) {
|
||||
if !fs.FileExists(fileName) {
|
||||
return fmt.Errorf("settings file not found: \"%s\"", fileName)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -30,7 +30,7 @@ func testDataPath(assetsPath string) string {
|
|||
}
|
||||
|
||||
func NewTestParams() *Params {
|
||||
assetsPath := file.ExpandFilename("../../assets")
|
||||
assetsPath := fs.ExpandFilename("../../assets")
|
||||
|
||||
testDataPath := testDataPath(assetsPath)
|
||||
|
||||
|
@ -53,7 +53,7 @@ func NewTestParams() *Params {
|
|||
}
|
||||
|
||||
func NewTestParamsError() *Params {
|
||||
assetsPath := file.ExpandFilename("../..")
|
||||
assetsPath := fs.ExpandFilename("../..")
|
||||
|
||||
testDataPath := testDataPath("../../assets")
|
||||
|
||||
|
@ -145,8 +145,8 @@ func (c *Config) RemoveTestData(t *testing.T) {
|
|||
}
|
||||
|
||||
func (c *Config) DownloadTestData(t *testing.T) {
|
||||
if file.Exists(TestDataZip) {
|
||||
hash := file.Hash(TestDataZip)
|
||||
if fs.FileExists(TestDataZip) {
|
||||
hash := fs.Hash(TestDataZip)
|
||||
|
||||
if hash != TestDataHash {
|
||||
os.Remove(TestDataZip)
|
||||
|
@ -154,17 +154,17 @@ func (c *Config) DownloadTestData(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
if !file.Exists(TestDataZip) {
|
||||
if !fs.FileExists(TestDataZip) {
|
||||
fmt.Printf("downloading latest test data zip file from %s\n", TestDataURL)
|
||||
|
||||
if err := file.Download(TestDataZip, TestDataURL); err != nil {
|
||||
if err := fs.Download(TestDataZip, TestDataURL); err != nil {
|
||||
fmt.Printf("Download failed: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) UnzipTestData(t *testing.T) {
|
||||
if _, err := file.Unzip(TestDataZip, testDataPath(c.AssetsPath())); err != nil {
|
||||
if _, err := fs.Unzip(TestDataZip, testDataPath(c.AssetsPath())); err != nil {
|
||||
t.Logf("could not unzip test data: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
@ -26,7 +26,7 @@ func TestNewTestParams(t *testing.T) {
|
|||
|
||||
assert.IsType(t, new(Params), c)
|
||||
|
||||
assert.Equal(t, file.ExpandFilename("../../assets"), c.AssetsPath)
|
||||
assert.Equal(t, fs.ExpandFilename("../../assets"), c.AssetsPath)
|
||||
assert.False(t, c.Debug)
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ func TestNewTestParamsError(t *testing.T) {
|
|||
|
||||
assert.IsType(t, new(Params), c)
|
||||
|
||||
assert.Equal(t, file.ExpandFilename("../.."), c.AssetsPath)
|
||||
assert.Equal(t, fs.ExpandFilename("../.."), c.AssetsPath)
|
||||
assert.Equal(t, "../../assets/testdata/cache", c.CachePath)
|
||||
assert.False(t, c.Debug)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
// Photo album
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
// Events
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
// An image or sidecar file that belongs to a photo
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/mutex"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
// Labels for photo, album and location categorization
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/maps"
|
||||
"github.com/photoprism/photoprism/internal/mutex"
|
||||
"github.com/photoprism/photoprism/internal/s2"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/s2"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var locationMutex = sync.Mutex{}
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// A photo can have multiple images and sidecar files
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/internal/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
// Shared photos and/or albums
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/maps/osm"
|
||||
"github.com/photoprism/photoprism/internal/s2"
|
||||
"github.com/photoprism/photoprism/pkg/s2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/melihmucuk/geocache"
|
||||
"github.com/photoprism/photoprism/internal/s2"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/s2"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
type Location struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ package osm
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/s2"
|
||||
"github.com/photoprism/photoprism/pkg/s2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package osm
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var labelTitles = map[string]string{
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
gc "github.com/patrickmn/go-cache"
|
||||
"github.com/photoprism/photoprism/internal/s2"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/s2"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// Location
|
||||
|
|
|
@ -3,7 +3,7 @@ package places
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/s2"
|
||||
"github.com/photoprism/photoprism/pkg/s2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
tf "github.com/tensorflow/tensorflow/tensorflow/go"
|
||||
"github.com/tensorflow/tensorflow/tensorflow/go/op"
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ func New(modelPath string) *Detector {
|
|||
|
||||
// File returns matching labels for a jpeg media file.
|
||||
func (t *Detector) File(filename string) (result Labels, err error) {
|
||||
if file.MimeType(filename) != "image/jpeg" {
|
||||
if fs.MimeType(filename) != "image/jpeg" {
|
||||
return result, fmt.Errorf("nsfw: \"%s\" is not a jpeg file", filename)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"math"
|
||||
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
"github.com/photoprism/photoprism/internal/colors"
|
||||
"github.com/photoprism/photoprism/pkg/colors"
|
||||
)
|
||||
|
||||
// Colors returns the ColorPerception of an image (only JPEG supported).
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/colors"
|
||||
"github.com/photoprism/photoprism/pkg/colors"
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,7 @@ func TestConvert_ToJpeg(t *testing.T) {
|
|||
|
||||
jpegFilename := conf.ImportPath() + "/fern_green.jpg"
|
||||
|
||||
assert.Truef(t, file.Exists(jpegFilename), "file does not exist: %s", jpegFilename)
|
||||
assert.Truef(t, fs.FileExists(jpegFilename), "file does not exist: %s", jpegFilename)
|
||||
|
||||
t.Logf("Testing RAW to JPEG convert with %s", jpegFilename)
|
||||
|
||||
|
@ -64,7 +64,7 @@ func TestConvert_ToJpeg(t *testing.T) {
|
|||
|
||||
imageRaw, _ := convert.ToJpeg(rawMediaFile)
|
||||
|
||||
assert.True(t, file.Exists(conf.ImportPath()+"/raw/IMG_2567.jpg"), "Jpeg file was not found - is Darktable installed?")
|
||||
assert.True(t, fs.FileExists(conf.ImportPath()+"/raw/IMG_2567.jpg"), "Jpeg file was not found - is Darktable installed?")
|
||||
|
||||
assert.NotEqual(t, rawFilename, imageRaw.filename)
|
||||
|
||||
|
@ -88,7 +88,7 @@ func TestConvert_Start(t *testing.T) {
|
|||
|
||||
jpegFilename := conf.ImportPath() + "/raw/canon_eos_6d.jpg"
|
||||
|
||||
assert.True(t, file.Exists(jpegFilename), "Jpeg file was not found - is Darktable installed?")
|
||||
assert.True(t, fs.FileExists(jpegFilename), "Jpeg file was not found - is Darktable installed?")
|
||||
|
||||
image, err := NewMediaFile(jpegFilename)
|
||||
|
||||
|
@ -104,15 +104,15 @@ func TestConvert_Start(t *testing.T) {
|
|||
|
||||
existingJpegFilename := conf.ImportPath() + "/raw/IMG_2567.jpg"
|
||||
|
||||
oldHash := file.Hash(existingJpegFilename)
|
||||
oldHash := fs.Hash(existingJpegFilename)
|
||||
|
||||
os.Remove(existingJpegFilename)
|
||||
|
||||
convert.Start(conf.ImportPath())
|
||||
|
||||
newHash := file.Hash(existingJpegFilename)
|
||||
newHash := fs.Hash(existingJpegFilename)
|
||||
|
||||
assert.True(t, file.Exists(existingJpegFilename), "Jpeg file was not found - is Darktable installed?")
|
||||
assert.True(t, fs.FileExists(existingJpegFilename), "Jpeg file was not found - is Darktable installed?")
|
||||
|
||||
assert.NotEqual(t, oldHash, newHash, "Fingerprint of old and new JPEG file must not be the same")
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/mutex"
|
||||
)
|
||||
|
||||
|
@ -158,7 +158,7 @@ func (imp *Import) Start(importPath string) {
|
|||
if imp.removeEmptyDirectories {
|
||||
// Remove empty directories from import path
|
||||
for _, directory := range directories {
|
||||
if file.IsEmpty(directory) {
|
||||
if fs.IsEmpty(directory) {
|
||||
if err := os.Remove(directory); err != nil {
|
||||
log.Errorf("import: could not deleted empty directory \"%s\" (%s)", directory, err)
|
||||
} else {
|
||||
|
@ -196,8 +196,8 @@ func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
|
|||
|
||||
result := pathName + string(os.PathSeparator) + fileName + fileExtension
|
||||
|
||||
for file.Exists(result) {
|
||||
if mediaFile.Hash() == file.Hash(result) {
|
||||
for fs.FileExists(result) {
|
||||
if mediaFile.Hash() == fs.Hash(result) {
|
||||
return result, fmt.Errorf("file already exists: %s", result)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/internal/meta"
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/txt"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
// Label represents a MediaFile label (automatically created).
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/djherbis/times"
|
||||
"github.com/photoprism/photoprism/internal/capture"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/meta"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ type MediaFile struct {
|
|||
dateCreated time.Time
|
||||
timeZone string
|
||||
hash string
|
||||
fileType file.Type
|
||||
fileType fs.Type
|
||||
mimeType string
|
||||
perceptualHash string
|
||||
width int
|
||||
|
@ -39,13 +39,13 @@ type MediaFile struct {
|
|||
|
||||
// NewMediaFile returns a new MediaFile.
|
||||
func NewMediaFile(filename string) (*MediaFile, error) {
|
||||
if !file.Exists(filename) {
|
||||
if !fs.FileExists(filename) {
|
||||
return nil, fmt.Errorf("file does not exist: %s", filename)
|
||||
}
|
||||
|
||||
instance := &MediaFile{
|
||||
filename: filename,
|
||||
fileType: file.TypeOther,
|
||||
fileType: fs.TypeOther,
|
||||
}
|
||||
|
||||
return instance, nil
|
||||
|
@ -241,7 +241,7 @@ func (m *MediaFile) CanonicalNameFromFileWithDirectory() string {
|
|||
// Hash return a sha1 hash of a MediaFile based on the filename.
|
||||
func (m *MediaFile) Hash() string {
|
||||
if len(m.hash) == 0 {
|
||||
m.hash = file.Hash(m.Filename())
|
||||
m.hash = fs.Hash(m.Filename())
|
||||
}
|
||||
|
||||
return m.hash
|
||||
|
@ -252,7 +252,7 @@ func (m *MediaFile) EditedFilename() string {
|
|||
basename := filepath.Base(m.filename)
|
||||
|
||||
if strings.ToUpper(basename[:4]) == "IMG_" && strings.ToUpper(basename[:5]) != "IMG_E" {
|
||||
if filename := filepath.Dir(m.filename) + string(os.PathSeparator) + basename[:4] + "E" + basename[4:]; file.Exists(filename) {
|
||||
if filename := filepath.Dir(m.filename) + string(os.PathSeparator) + basename[:4] + "E" + basename[4:]; fs.FileExists(filename) {
|
||||
return filename
|
||||
}
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ func (m *MediaFile) MimeType() string {
|
|||
return m.mimeType
|
||||
}
|
||||
|
||||
m.mimeType = file.MimeType(m.Filename())
|
||||
m.mimeType = fs.MimeType(m.Filename())
|
||||
|
||||
return m.mimeType
|
||||
}
|
||||
|
@ -409,7 +409,7 @@ func (m *MediaFile) openFile() (*os.File, error) {
|
|||
|
||||
// Exists checks if a media file exists by filename.
|
||||
func (m *MediaFile) Exists() bool {
|
||||
return file.Exists(m.Filename())
|
||||
return fs.FileExists(m.Filename())
|
||||
}
|
||||
|
||||
// Remove a media file.
|
||||
|
@ -488,17 +488,17 @@ func (m *MediaFile) IsJpeg() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
return m.MimeType() == file.MimeTypeJpeg
|
||||
return m.MimeType() == fs.MimeTypeJpeg
|
||||
}
|
||||
|
||||
// Type returns the type of the media file.
|
||||
func (m *MediaFile) Type() file.Type {
|
||||
return file.Ext[m.Extension()]
|
||||
func (m *MediaFile) Type() fs.Type {
|
||||
return fs.Ext[m.Extension()]
|
||||
}
|
||||
|
||||
// HasType returns true if this media file is of a given type.
|
||||
func (m *MediaFile) HasType(t file.Type) bool {
|
||||
if t == file.TypeJpeg {
|
||||
func (m *MediaFile) HasType(t fs.Type) bool {
|
||||
if t == fs.TypeJpeg {
|
||||
return m.IsJpeg()
|
||||
}
|
||||
|
||||
|
@ -507,29 +507,29 @@ func (m *MediaFile) HasType(t file.Type) bool {
|
|||
|
||||
// IsRaw returns true if this media file a RAW file.
|
||||
func (m *MediaFile) IsRaw() bool {
|
||||
return m.HasType(file.TypeRaw)
|
||||
return m.HasType(fs.TypeRaw)
|
||||
}
|
||||
|
||||
// IsPng returns true if this media file a PNG file.
|
||||
func (m *MediaFile) IsPng() bool {
|
||||
return m.HasType(file.TypePng)
|
||||
return m.HasType(fs.TypePng)
|
||||
}
|
||||
|
||||
// IsTiff returns true if this media file a TIFF file.
|
||||
func (m *MediaFile) IsTiff() bool {
|
||||
return m.HasType(file.TypeTiff)
|
||||
return m.HasType(fs.TypeTiff)
|
||||
}
|
||||
|
||||
// IsImageOther returns true this media file a PNG, GIF, BMP or TIFF file.
|
||||
func (m *MediaFile) IsImageOther() bool {
|
||||
switch m.Type() {
|
||||
case file.TypeBitmap:
|
||||
case fs.TypeBitmap:
|
||||
return true
|
||||
case file.TypeGif:
|
||||
case fs.TypeGif:
|
||||
return true
|
||||
case file.TypePng:
|
||||
case fs.TypePng:
|
||||
return true
|
||||
case file.TypeTiff:
|
||||
case fs.TypeTiff:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
@ -538,23 +538,23 @@ func (m *MediaFile) IsImageOther() bool {
|
|||
|
||||
// IsHEIF returns true if this media file is a High Efficiency Image File Format file.
|
||||
func (m *MediaFile) IsHEIF() bool {
|
||||
return m.HasType(file.TypeHEIF)
|
||||
return m.HasType(fs.TypeHEIF)
|
||||
}
|
||||
|
||||
// IsSidecar returns true if this media file is a sidecar file (containing metadata).
|
||||
func (m *MediaFile) IsSidecar() bool {
|
||||
switch m.Type() {
|
||||
case file.TypeXMP:
|
||||
case fs.TypeXMP:
|
||||
return true
|
||||
case file.TypeAAE:
|
||||
case fs.TypeAAE:
|
||||
return true
|
||||
case file.TypeXML:
|
||||
case fs.TypeXML:
|
||||
return true
|
||||
case file.TypeYaml:
|
||||
case fs.TypeYaml:
|
||||
return true
|
||||
case file.TypeText:
|
||||
case fs.TypeText:
|
||||
return true
|
||||
case file.TypeMarkdown:
|
||||
case fs.TypeMarkdown:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
@ -564,7 +564,7 @@ func (m *MediaFile) IsSidecar() bool {
|
|||
// IsVideo returns true if this media file is a video file.
|
||||
func (m *MediaFile) IsVideo() bool {
|
||||
switch m.Type() {
|
||||
case file.TypeMovie:
|
||||
case fs.TypeMovie:
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -582,9 +582,9 @@ func (m *MediaFile) Jpeg() (*MediaFile, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
jpegFilename := fmt.Sprintf("%s.%s", m.DirectoryBasename(), file.TypeJpeg)
|
||||
jpegFilename := fmt.Sprintf("%s.%s", m.DirectoryBasename(), fs.TypeJpeg)
|
||||
|
||||
if !file.Exists(jpegFilename) {
|
||||
if !fs.FileExists(jpegFilename) {
|
||||
return nil, fmt.Errorf("jpeg file does not exist: %s", jpegFilename)
|
||||
}
|
||||
|
||||
|
@ -742,7 +742,7 @@ func (m *MediaFile) CreateDefaultThumbnails(thumbPath string, force bool) (err e
|
|||
|
||||
return err
|
||||
} else {
|
||||
if !force && file.Exists(fileName) {
|
||||
if !force && fs.FileExists(fileName) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
|
@ -515,7 +515,7 @@ func TestMediaFile_Move(t *testing.T) {
|
|||
f, err := NewMediaFile(conf.ExamplesPath() + "/table_white.jpg")
|
||||
assert.Nil(t, err)
|
||||
f.Copy(origName)
|
||||
assert.True(t, file.Exists(origName))
|
||||
assert.True(t, fs.FileExists(origName))
|
||||
|
||||
m, err := NewMediaFile(origName)
|
||||
assert.Nil(t, err)
|
||||
|
@ -524,7 +524,7 @@ func TestMediaFile_Move(t *testing.T) {
|
|||
t.Errorf("failed to move: %s", err)
|
||||
}
|
||||
|
||||
assert.True(t, file.Exists(destName))
|
||||
assert.True(t, fs.FileExists(destName))
|
||||
assert.Equal(t, destName, m.Filename())
|
||||
}
|
||||
|
||||
|
@ -540,7 +540,7 @@ func TestMediaFile_Copy(t *testing.T) {
|
|||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/table_white.jpg")
|
||||
assert.Nil(t, err)
|
||||
mediaFile.Copy(tmpPath + "table_whitecopy.jpg")
|
||||
assert.True(t, file.Exists(tmpPath+"table_whitecopy.jpg"))
|
||||
assert.True(t, fs.FileExists(tmpPath+"table_whitecopy.jpg"))
|
||||
}
|
||||
|
||||
func TestMediaFile_Extension(t *testing.T) {
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
Package config contains random token functions.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
https://github.com/photoprism/photoprism/wiki
|
||||
*/
|
||||
package rnd
|
||||
|
||||
import (
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
var log = event.Log
|
|
@ -9,20 +9,20 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/file"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
func ResampleOptions(opts ...ResampleOption) (method ResampleOption, filter imaging.ResampleFilter, format file.Type) {
|
||||
func ResampleOptions(opts ...ResampleOption) (method ResampleOption, filter imaging.ResampleFilter, format fs.Type) {
|
||||
method = ResampleFit
|
||||
filter = imaging.Lanczos
|
||||
format = file.TypeJpeg
|
||||
format = fs.TypeJpeg
|
||||
|
||||
for _, option := range opts {
|
||||
switch option {
|
||||
case ResamplePng:
|
||||
format = file.TypePng
|
||||
format = fs.TypePng
|
||||
case ResampleNearestNeighbor:
|
||||
filter = imaging.NearestNeighbor
|
||||
case ResampleLanczos:
|
||||
|
@ -116,7 +116,7 @@ func FromFile(imageFilename string, hash string, thumbPath string, width, height
|
|||
return "", err
|
||||
}
|
||||
|
||||
if file.Exists(fileName) {
|
||||
if fs.FileExists(fileName) {
|
||||
return fileName, nil
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ func Create(img image.Image, fileName string, width, height int, opts ...Resampl
|
|||
|
||||
var saveOption imaging.EncodeOption
|
||||
|
||||
if filepath.Ext(fileName) == "."+string(file.TypePng) {
|
||||
if filepath.Ext(fileName) == "."+string(fs.TypePng) {
|
||||
saveOption = imaging.PNGCompressionLevel(png.DefaultCompression)
|
||||
} else if width <= 150 && height <= 150 {
|
||||
saveOption = imaging.JPEGQuality(JpegQualitySmall)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,19 +0,0 @@
|
|||
package txt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var logBuffer bytes.Buffer
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
log = logrus.StandardLogger()
|
||||
log.Out = &logBuffer
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
code := m.Run()
|
||||
os.Exit(code)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
This package encapsulates color classification.
|
||||
Package colors provides types and functions for color classification.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/lucasb-eyer/go-colorful"
|
||||
)
|
||||
|
||||
// TODO: Requires documentation
|
||||
type ColorPerception struct {
|
||||
Colors Colors
|
||||
MainColor Color
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
This package encapsulates file related constants and functions.
|
||||
Package fs provides filesystem related constants and functions.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
https://github.com/photoprism/photoprism/wiki
|
||||
*/
|
||||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
|
@ -16,14 +16,10 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
var log = event.Log
|
||||
|
||||
// Returns true if file exists
|
||||
func Exists(filename string) bool {
|
||||
// FileExists returns true if file exists (false for directories).
|
||||
func FileExists(filename string) bool {
|
||||
info, err := os.Stat(filename)
|
||||
|
||||
return err == nil && !info.IsDir()
|
||||
|
@ -40,7 +36,7 @@ func Overwrite(fileName string, data []byte) bool {
|
|||
return err == nil
|
||||
}
|
||||
|
||||
// Returns full path; ~ replaced with actual home directory
|
||||
// Returns full path of a file, "~" is replaced with home directory
|
||||
func ExpandFilename(filename string) string {
|
||||
if filename == "" {
|
||||
return ""
|
||||
|
@ -104,7 +100,7 @@ func copyToFile(f *zip.File, dest string) (fileName string, err error) {
|
|||
return fileName, nil
|
||||
}
|
||||
|
||||
// Download a file from a URL
|
||||
// Download downloads a file from a URL.
|
||||
func Download(filepath string, url string) error {
|
||||
os.MkdirAll("/tmp/photoprism", os.ModePerm)
|
||||
|
||||
|
@ -136,6 +132,7 @@ func Download(filepath string, url string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// IsEmpty returns true if a directory is empty.
|
||||
func IsEmpty(path string) bool {
|
||||
f, err := os.Open(path)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
@ -9,8 +9,8 @@ import (
|
|||
)
|
||||
|
||||
func TestExists(t *testing.T) {
|
||||
assert.True(t, Exists("./testdata/test.jpg"))
|
||||
assert.False(t, Exists("./foo.jpg"))
|
||||
assert.True(t, FileExists("./testdata/test.jpg"))
|
||||
assert.False(t, FileExists("./foo.jpg"))
|
||||
}
|
||||
|
||||
func TestOverwrite(t *testing.T) {
|
|
@ -1,4 +1,4 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
|
@ -7,7 +7,7 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
// Returns sha1 hash of file as string
|
||||
// Hash returns the sha1 hash of file as string.
|
||||
func Hash(filename string) string {
|
||||
var result []byte
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"testing"
|
|
@ -1,15 +1,15 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
// MimeType returns the mime type of a file, empty string if unknown.
|
||||
func MimeType(filename string) string {
|
||||
handle, err := os.Open(filename)
|
||||
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ func MimeType(filename string) string {
|
|||
_, err = handle.Read(buffer)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("could not read file to determine mime type: %s", filename)
|
||||
return ""
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"testing"
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -1,4 +1,4 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
_ "image/gif" // Import for image.
|
||||
|
@ -42,11 +42,10 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
// MimeTypeJpeg is jpeg image type
|
||||
MimeTypeJpeg = "image/jpeg"
|
||||
)
|
||||
|
||||
// Ext lists all the available and supported image file formats.
|
||||
// Ext contains the filename extensions of file formats known to PhotoPrism.
|
||||
var Ext = map[string]Type{
|
||||
".bmp": TypeBitmap,
|
||||
".gif": TypeGif,
|
|
@ -1,4 +1,4 @@
|
|||
package file
|
||||
package fs
|
||||
|
||||
import (
|
||||
"archive/zip"
|
6
pkg/rnd/password.go
Normal file
6
pkg/rnd/password.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package rnd
|
||||
|
||||
// Password returns a random password with 8 characters as string.
|
||||
func Password() string {
|
||||
return Token(8)
|
||||
}
|
16
pkg/rnd/ppid.go
Normal file
16
pkg/rnd/ppid.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package rnd
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PPID returns a unique id with prefix as string.
|
||||
func PPID(prefix rune) string {
|
||||
result := make([]byte, 0, 17)
|
||||
result = append(result, byte(prefix))
|
||||
result = append(result, strconv.FormatInt(time.Now().UTC().Unix(), 36)[0:6]...)
|
||||
result = append(result, Token(10)...)
|
||||
|
||||
return string(result)
|
||||
}
|
8
pkg/rnd/rnd.go
Normal file
8
pkg/rnd/rnd.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
Package rnd provides random token functions.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
https://github.com/photoprism/photoprism/wiki
|
||||
*/
|
||||
package rnd
|
|
@ -3,22 +3,21 @@ package rnd
|
|||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// Token returns a random token with length of up to 10 characters.
|
||||
func Token(size uint) string {
|
||||
if size > 10 || size < 1 {
|
||||
log.Fatalf("size out of range: %d", size)
|
||||
panic(fmt.Sprintf("size out of range: %d", size))
|
||||
}
|
||||
|
||||
result := make([]byte, 0, 14)
|
||||
b := make([]byte, 8)
|
||||
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
log.Fatal(err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
randomInt := binary.BigEndian.Uint64(b)
|
||||
|
@ -31,20 +30,3 @@ func Token(size uint) string {
|
|||
|
||||
return string(result[:size])
|
||||
}
|
||||
|
||||
func Password() string {
|
||||
return Token(8)
|
||||
}
|
||||
|
||||
func PPID(prefix rune) string {
|
||||
result := make([]byte, 0, 17)
|
||||
result = append(result, byte(prefix))
|
||||
result = append(result, strconv.FormatInt(time.Now().UTC().Unix(), 36)[0:6]...)
|
||||
result = append(result, Token(10)...)
|
||||
|
||||
return string(result)
|
||||
}
|
||||
|
||||
func UUID() string {
|
||||
return uuid.NewV4().String()
|
||||
}
|
10
pkg/rnd/uuid.go
Normal file
10
pkg/rnd/uuid.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package rnd
|
||||
|
||||
import (
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// UUID returns a standard, random UUID as string.
|
||||
func UUID() string {
|
||||
return uuid.NewV4().String()
|
||||
}
|
|
@ -1,30 +1,40 @@
|
|||
/*
|
||||
Package s2 encapsulates Google's S2 library.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
https://github.com/photoprism/photoprism/wiki
|
||||
|
||||
...and in the Google S2 documentation:
|
||||
|
||||
https://s2geometry.io/
|
||||
|
||||
*/
|
||||
package s2
|
||||
|
||||
import (
|
||||
gs2 "github.com/golang/geo/s2"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
var log = event.Log
|
||||
var Level = 21
|
||||
// Default cell level, see https://s2geometry.io/resources/s2cell_statistics.html.
|
||||
var DefaultLevel = 21
|
||||
|
||||
// Token returns the S2 cell token for coordinates using the default level.
|
||||
func Token(lat, lng float64) string {
|
||||
return TokenLevel(lat, lng, Level)
|
||||
return TokenLevel(lat, lng, DefaultLevel)
|
||||
}
|
||||
|
||||
// Token returns the S2 cell token for coordinates.
|
||||
func TokenLevel(lat, lng float64, level int) string {
|
||||
if lat == 0.0 && lng == 0.0 {
|
||||
log.Debugf("s2: no values for latitude and longitude")
|
||||
return ""
|
||||
}
|
||||
|
||||
if lat < -90 || lat > 90 {
|
||||
log.Warnf("s2: latitude out of range (%f)", lat)
|
||||
return ""
|
||||
}
|
||||
|
||||
if lng < -180 || lng > 180 {
|
||||
log.Warnf("s2: longitude out of range (%f)", lng)
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -32,9 +42,9 @@ func TokenLevel(lat, lng float64, level int) string {
|
|||
return gs2.CellIDFromLatLng(l).Parent(level).ToToken()
|
||||
}
|
||||
|
||||
// LatLng returns the coordinates for a S2 cell token.
|
||||
func LatLng(token string) (lat, lng float64) {
|
||||
if token == "" || token == "-" {
|
||||
log.Warn("s2: empty token")
|
||||
return 0.0, 0.0
|
||||
}
|
||||
|
|
@ -87,3 +87,11 @@ func TestTokenLevel(t *testing.T) {
|
|||
assert.Equal(t, expected, token)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLatLng(t *testing.T) {
|
||||
t.Run("Wildgehege", func(t *testing.T) {
|
||||
lat, lng := LatLng("4799e370ca54c8b9")
|
||||
assert.Equal(t, 48.56344835921243, lat)
|
||||
assert.Equal(t, 8.996878323369781, lng)
|
||||
})
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package txt
|
||||
|
||||
// Months contains all month names in English.
|
||||
var Months = [...]string{
|
||||
"Unknown",
|
||||
"January",
|
|
@ -48,8 +48,9 @@ func main() {
|
|||
}
|
||||
|
||||
var packageTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
|
||||
package util
|
||||
package txt
|
||||
|
||||
// Stopwords contains a list of stopwords for full-text indexing.
|
||||
var Stopwords = map[string]bool{
|
||||
{{- range .Words }}
|
||||
{{ printf "%q" . }}: true,
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
var KeywordsRegexp = regexp.MustCompile("[\\p{L}]{3,}")
|
||||
|
||||
// Keywords extracts keywords for indexing and returns them as string slice.
|
||||
func Keywords(s string) (results []string) {
|
||||
all := KeywordsRegexp.FindAllString(s, -1)
|
||||
|
4984
pkg/txt/stopwords.go
Normal file
4984
pkg/txt/stopwords.go
Normal file
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
var ContainsNumberRegexp = regexp.MustCompile("\\d+")
|
||||
|
||||
// ContainsNumber returns true if string contains a number.
|
||||
func ContainsNumber(s string) bool {
|
||||
return ContainsNumberRegexp.MatchString(s)
|
||||
}
|
||||
|
@ -36,6 +37,7 @@ func isSeparator(r rune) bool {
|
|||
return unicode.IsSpace(r)
|
||||
}
|
||||
|
||||
// UcFirst returns the string with the first character converted to uppercase.
|
||||
func UcFirst(str string) string {
|
||||
for i, v := range str {
|
||||
return string(unicode.ToUpper(v)) + str[i+1:]
|
||||
|
@ -43,6 +45,7 @@ func UcFirst(str string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// Title returns the string with all the first character of each word converted to uppercase.
|
||||
func Title(s string) string {
|
||||
prev := ' '
|
||||
return strings.Map(
|
|
@ -1,5 +1,6 @@
|
|||
package txt
|
||||
|
||||
// List of titles and ranks in lowercase, see https://en.wikipedia.org/wiki/List_of_titles.
|
||||
var TitlesAndRanks = map[string]bool {
|
||||
"emperor": true,
|
||||
"caliph": true,
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Package txt contains text / linguistics related code.
|
||||
Package txt provides text / linguistics related functionality.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
|
@ -7,10 +7,4 @@ https://github.com/photoprism/photoprism/wiki
|
|||
*/
|
||||
package txt
|
||||
|
||||
import (
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
//go:generate go run gen.go
|
||||
|
||||
var log = event.Log
|
Loading…
Reference in a new issue