Rename context package to config and fsutil to util

This commit is contained in:
Michael Mayer 2019-05-06 23:18:10 +02:00
parent cf8d4ce29b
commit 0ddef3a02d
49 changed files with 330 additions and 322 deletions

View file

@ -4,7 +4,8 @@ import (
"os"
"github.com/photoprism/photoprism/internal/commands"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@ -17,7 +18,7 @@ func main() {
app.Version = version
app.Copyright = "(c) 2018-2019 The PhotoPrism contributors <hello@photoprism.org>"
app.EnableBashCompletion = true
app.Flags = context.GlobalFlags
app.Flags = config.GlobalFlags
app.Commands = []cli.Command{
commands.ConfigCommand,
@ -31,5 +32,7 @@ func main() {
commands.VersionCommand,
}
app.Run(os.Args)
if err := app.Run(os.Args); err != nil {
log.Error(err)
}
}

View file

@ -5,18 +5,18 @@ import (
"net/http/httptest"
"github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
)
// API test helper
func NewApiTest() (app *gin.Engine, router *gin.RouterGroup, ctx *context.Context) {
ctx = context.TestContext()
func NewApiTest() (app *gin.Engine, router *gin.RouterGroup, conf *config.Config) {
conf = config.TestConfig()
gin.SetMode(gin.TestMode)
app = gin.New()
router = app.Group("/api/v1")
return app, router, ctx
return app, router, conf
}
// See https://medium.com/@craigchilds94/testing-gin-json-responses-1f258ce3b0b1

View file

@ -4,7 +4,7 @@ import (
"net/http"
"strconv"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
log "github.com/sirupsen/logrus"
"github.com/gin-gonic/gin"
@ -27,10 +27,10 @@ import (
// before: date Find photos taken before (format: "2006-01-02")
// after: date Find photos taken after (format: "2006-01-02")
// favorites: bool Find favorites only
func GetPhotos(router *gin.RouterGroup, ctx *context.Context) {
func GetPhotos(router *gin.RouterGroup, conf *config.Config) {
router.GET("/photos", func(c *gin.Context) {
var form forms.PhotoSearchForm
search := photoprism.NewSearch(ctx.OriginalsPath(), ctx.Db())
search := photoprism.NewSearch(conf.OriginalsPath(), conf.Db())
err := c.MustBindWith(&form, binding.Form)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
@ -53,9 +53,9 @@ func GetPhotos(router *gin.RouterGroup, ctx *context.Context) {
//
// Parameters:
// id: int Photo ID as returned by the API
func LikePhoto(router *gin.RouterGroup, ctx *context.Context) {
func LikePhoto(router *gin.RouterGroup, conf *config.Config) {
router.POST("/photos/:id/like", func(c *gin.Context) {
search := photoprism.NewSearch(ctx.OriginalsPath(), ctx.Db())
search := photoprism.NewSearch(conf.OriginalsPath(), conf.Db())
photoID, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
log.Errorf("could not find image for id: %s", err.Error())
@ -71,7 +71,7 @@ func LikePhoto(router *gin.RouterGroup, ctx *context.Context) {
}
photo.PhotoFavorite = true
ctx.Db().Save(&photo)
conf.Db().Save(&photo)
c.JSON(http.StatusOK, http.Response{})
})
}
@ -80,9 +80,9 @@ func LikePhoto(router *gin.RouterGroup, ctx *context.Context) {
//
// Parameters:
// id: int Photo ID as returned by the API
func DislikePhoto(router *gin.RouterGroup, ctx *context.Context) {
func DislikePhoto(router *gin.RouterGroup, conf *config.Config) {
router.DELETE("/photos/:id/like", func(c *gin.Context) {
search := photoprism.NewSearch(ctx.OriginalsPath(), ctx.Db())
search := photoprism.NewSearch(conf.OriginalsPath(), conf.Db())
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
log.Errorf("could not find image for id: %s", err.Error())
@ -98,7 +98,7 @@ func DislikePhoto(router *gin.RouterGroup, ctx *context.Context) {
}
photo.PhotoFavorite = false
ctx.Db().Save(&photo)
conf.Db().Save(&photo)
c.JSON(http.StatusOK, http.Response{})
})
}

View file

@ -4,7 +4,7 @@ import (
"fmt"
"strconv"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
log "github.com/sirupsen/logrus"
"github.com/gin-gonic/gin"
@ -23,7 +23,7 @@ var photoIconSvg = []byte(`
// type: string Format, either "fit" or "square"
// size: int Size in pixels
// hash: string The file hash as returned by the search API
func GetThumbnail(router *gin.RouterGroup, ctx *context.Context) {
func GetThumbnail(router *gin.RouterGroup, conf *config.Config) {
router.GET("/thumbnails/:type/:size/:hash", func(c *gin.Context) {
fileHash := c.Param("hash")
thumbnailType := c.Param("type")
@ -34,7 +34,7 @@ func GetThumbnail(router *gin.RouterGroup, ctx *context.Context) {
return
}
search := photoprism.NewSearch(ctx.OriginalsPath(), ctx.Db())
search := photoprism.NewSearch(conf.OriginalsPath(), conf.Db())
file, err := search.FindFileByHash(fileHash)
if err != nil {
@ -42,7 +42,7 @@ func GetThumbnail(router *gin.RouterGroup, ctx *context.Context) {
return
}
fileName := fmt.Sprintf("%s/%s", ctx.OriginalsPath(), file.FileName)
fileName := fmt.Sprintf("%s/%s", conf.OriginalsPath(), file.FileName)
mediaFile, err := photoprism.NewMediaFile(fileName)
if err != nil {
@ -51,20 +51,20 @@ func GetThumbnail(router *gin.RouterGroup, ctx *context.Context) {
// Set missing flag so that the file doesn't show up in search results anymore
file.FileMissing = true
ctx.Db().Save(&file)
conf.Db().Save(&file)
return
}
switch thumbnailType {
case "fit":
if thumbnail, err := mediaFile.Thumbnail(ctx.ThumbnailsPath(), size); err == nil {
if thumbnail, err := mediaFile.Thumbnail(conf.ThumbnailsPath(), size); err == nil {
c.File(thumbnail.Filename())
} else {
log.Errorf("could not create thumbnail: %s", err.Error())
c.Data(400, "image/svg+xml", photoIconSvg)
}
case "square":
if thumbnail, err := mediaFile.SquareThumbnail(ctx.ThumbnailsPath(), size); err == nil {
if thumbnail, err := mediaFile.SquareThumbnail(conf.ThumbnailsPath(), size); err == nil {
c.File(thumbnail.Filename())
} else {
log.Errorf("could not create square thumbnail: %s", err.Error())

View file

@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/urfave/cli"
)
@ -15,42 +15,42 @@ var ConfigCommand = cli.Command{
}
func configAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
fmt.Printf("NAME VALUE\n")
fmt.Printf("name %s\n", app.Name())
fmt.Printf("version %s\n", app.Version())
fmt.Printf("copyright %s\n", app.Copyright())
fmt.Printf("debug %t\n", app.Debug())
fmt.Printf("read-only %t\n", app.ReadOnly())
fmt.Printf("log-level %s\n", app.LogLevel())
fmt.Printf("config-file %s\n", app.ConfigFile())
fmt.Printf("name %s\n", conf.Name())
fmt.Printf("version %s\n", conf.Version())
fmt.Printf("copyright %s\n", conf.Copyright())
fmt.Printf("debug %t\n", conf.Debug())
fmt.Printf("read-only %t\n", conf.ReadOnly())
fmt.Printf("log-level %s\n", conf.LogLevel())
fmt.Printf("config-file %s\n", conf.ConfigFile())
fmt.Printf("database-driver %s\n", app.DatabaseDriver())
fmt.Printf("database-dsn %s\n", app.DatabaseDsn())
fmt.Printf("database-driver %s\n", conf.DatabaseDriver())
fmt.Printf("database-dsn %s\n", conf.DatabaseDsn())
fmt.Printf("http-host %s\n", app.HttpServerHost())
fmt.Printf("http-port %d\n", app.HttpServerPort())
fmt.Printf("http-mode %s\n", app.HttpServerMode())
fmt.Printf("http-host %s\n", conf.HttpServerHost())
fmt.Printf("http-port %d\n", conf.HttpServerPort())
fmt.Printf("http-mode %s\n", conf.HttpServerMode())
fmt.Printf("sql-host %s\n", app.SqlServerHost())
fmt.Printf("sql-port %d\n", app.SqlServerPort())
fmt.Printf("sql-password %s\n", app.SqlServerPassword())
fmt.Printf("sql-path %s\n", app.SqlServerPath())
fmt.Printf("sql-host %s\n", conf.SqlServerHost())
fmt.Printf("sql-port %d\n", conf.SqlServerPort())
fmt.Printf("sql-password %s\n", conf.SqlServerPassword())
fmt.Printf("sql-path %s\n", conf.SqlServerPath())
fmt.Printf("assets-path %s\n", app.AssetsPath())
fmt.Printf("originals-path %s\n", app.OriginalsPath())
fmt.Printf("import-path %s\n", app.ImportPath())
fmt.Printf("export-path %s\n", app.ExportPath())
fmt.Printf("cache-path %s\n", app.CachePath())
fmt.Printf("thumbnails-path %s\n", app.ThumbnailsPath())
fmt.Printf("tf-model-path %s\n", app.TensorFlowModelPath())
fmt.Printf("templates-path %s\n", app.HttpTemplatesPath())
fmt.Printf("favicons-path %s\n", app.HttpFaviconsPath())
fmt.Printf("public-path %s\n", app.HttpPublicPath())
fmt.Printf("public-build-path %s\n", app.HttpPublicBuildPath())
fmt.Printf("assets-path %s\n", conf.AssetsPath())
fmt.Printf("originals-path %s\n", conf.OriginalsPath())
fmt.Printf("import-path %s\n", conf.ImportPath())
fmt.Printf("export-path %s\n", conf.ExportPath())
fmt.Printf("cache-path %s\n", conf.CachePath())
fmt.Printf("thumbnails-path %s\n", conf.ThumbnailsPath())
fmt.Printf("tf-model-path %s\n", conf.TensorFlowModelPath())
fmt.Printf("templates-path %s\n", conf.HttpTemplatesPath())
fmt.Printf("favicons-path %s\n", conf.HttpFaviconsPath())
fmt.Printf("public-path %s\n", conf.HttpPublicPath())
fmt.Printf("public-build-path %s\n", conf.HttpPublicBuildPath())
fmt.Printf("darktable-cli %s\n", app.DarktableCli())
fmt.Printf("darktable-cli %s\n", conf.DarktableCli())
return nil
}

View file

@ -3,16 +3,17 @@ package commands
import (
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert"
)
func TestConfigCommand(t *testing.T) {
var err error
ctx := context.CliTestContext()
ctx := config.CliTestContext()
output := context.CaptureOutput(func() {
output := util.CaptureOutput(func() {
err = ConfigCommand.Run(ctx)
})

View file

@ -1,7 +1,7 @@
package commands
import (
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -15,17 +15,17 @@ var ConvertCommand = cli.Command{
}
func convertAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
if err := app.CreateDirectories(); err != nil {
if err := conf.CreateDirectories(); err != nil {
return err
}
log.Infof("converting RAW images in %s to JPEG", app.OriginalsPath())
log.Infof("converting RAW images in %s to JPEG", conf.OriginalsPath())
converter := photoprism.NewConverter(app.DarktableCli())
converter := photoprism.NewConverter(conf.DarktableCli())
converter.ConvertAll(app.OriginalsPath())
converter.ConvertAll(conf.OriginalsPath())
log.Infof("image conversion complete")

View file

@ -6,7 +6,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/araddon/dateparse"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
"github.com/urfave/cli"
)
@ -40,9 +40,9 @@ var exportFlags = []cli.Flag{
}
func exportAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
if err := app.CreateDirectories(); err != nil {
if err := conf.CreateDirectories(); err != nil {
return err
}
@ -70,15 +70,17 @@ func exportAction(ctx *cli.Context) error {
}
}
exportPath := fmt.Sprintf("%s/%s", app.ExportPath(), name)
exportPath := fmt.Sprintf("%s/%s", conf.ExportPath(), name)
size := ctx.Int("size")
originals := photoprism.FindOriginalsByDate(app.OriginalsPath(), afterDate, beforeDate)
originals := photoprism.FindOriginalsByDate(conf.OriginalsPath(), afterDate, beforeDate)
log.Infof("exporting photos to %s", exportPath)
photoprism.ExportPhotosFromOriginals(originals, app.ThumbnailsPath(), exportPath, size)
log.Infof("photo export complete")
if err := photoprism.ExportPhotosFromOriginals(originals, conf.ThumbnailsPath(), exportPath, size); err != nil {
log.Error(err)
} else {
log.Infof("photo export complete")
}
return nil
}

View file

@ -1,7 +1,7 @@
package commands
import (
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -15,25 +15,25 @@ var ImportCommand = cli.Command{
}
func importAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
if err := app.CreateDirectories(); err != nil {
if err := conf.CreateDirectories(); err != nil {
return err
}
app.MigrateDb()
conf.MigrateDb()
log.Infof("importing photos from %s", app.ImportPath())
log.Infof("importing photos from %s", conf.ImportPath())
tensorFlow := photoprism.NewTensorFlow(app.TensorFlowModelPath())
tensorFlow := photoprism.NewTensorFlow(conf.TensorFlowModelPath())
indexer := photoprism.NewIndexer(app.OriginalsPath(), tensorFlow, app.Db())
indexer := photoprism.NewIndexer(conf.OriginalsPath(), tensorFlow, conf.Db())
converter := photoprism.NewConverter(app.DarktableCli())
converter := photoprism.NewConverter(conf.DarktableCli())
importer := photoprism.NewImporter(app.OriginalsPath(), indexer, converter)
importer := photoprism.NewImporter(conf.OriginalsPath(), indexer, converter)
importer.ImportPhotosFromDirectory(app.ImportPath())
importer.ImportPhotosFromDirectory(conf.ImportPath())
log.Info("photo import complete")

View file

@ -1,7 +1,7 @@
package commands
import (
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -15,25 +15,25 @@ var IndexCommand = cli.Command{
}
func indexAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
if err := app.CreateDirectories(); err != nil {
if err := conf.CreateDirectories(); err != nil {
return err
}
app.MigrateDb()
conf.MigrateDb()
log.Infof("indexing photos in %s", app.OriginalsPath())
log.Infof("indexing photos in %s", conf.OriginalsPath())
tensorFlow := photoprism.NewTensorFlow(app.TensorFlowModelPath())
tensorFlow := photoprism.NewTensorFlow(conf.TensorFlowModelPath())
indexer := photoprism.NewIndexer(app.OriginalsPath(), tensorFlow, app.Db())
indexer := photoprism.NewIndexer(conf.OriginalsPath(), tensorFlow, conf.Db())
files := indexer.IndexAll()
log.Infof("indexed %d files", len(files))
app.Shutdown()
conf.Shutdown()
return nil
}

View file

@ -1,7 +1,7 @@
package commands
import (
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@ -14,15 +14,15 @@ var MigrateCommand = cli.Command{
}
func migrateAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
log.Infoln("migrating database")
app.MigrateDb()
conf.MigrateDb()
log.Infoln("database migration complete")
app.Shutdown()
conf.Shutdown()
return nil
}

View file

@ -3,7 +3,7 @@ package commands
import (
log "github.com/sirupsen/logrus"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/server"
"github.com/urfave/cli"
)
@ -38,21 +38,21 @@ var startFlags = []cli.Flag{
}
func startAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
if app.HttpServerPort() < 1 {
if conf.HttpServerPort() < 1 {
log.Fatal("server port must be a positive integer")
}
if err := app.CreateDirectories(); err != nil {
if err := conf.CreateDirectories(); err != nil {
log.Fatal(err)
}
app.MigrateDb()
conf.MigrateDb()
log.Infof("starting web server at %s:%d", app.HttpServerHost(), app.HttpServerPort())
log.Infof("starting web server at %s:%d", conf.HttpServerHost(), conf.HttpServerPort())
server.Start(app)
server.Start(conf)
return nil
}

View file

@ -1,7 +1,7 @@
package commands
import (
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -29,13 +29,13 @@ var ThumbnailsCommand = cli.Command{
}
func thumbnailsAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
if err := app.CreateDirectories(); err != nil {
if err := conf.CreateDirectories(); err != nil {
return err
}
log.Infof("creating thumbnails in \"%s\"", app.ThumbnailsPath())
log.Infof("creating thumbnails in \"%s\"", conf.ThumbnailsPath())
sizes := ctx.IntSlice("size")
@ -49,7 +49,7 @@ func thumbnailsAction(ctx *cli.Context) error {
}
for _, size := range sizes {
photoprism.CreateThumbnailsFromOriginals(app.OriginalsPath(), app.ThumbnailsPath(), size, ctx.Bool("square"))
photoprism.CreateThumbnailsFromOriginals(conf.OriginalsPath(), conf.ThumbnailsPath(), size, ctx.Bool("square"))
}
log.Info("thumbnails created")

View file

@ -3,7 +3,7 @@ package commands
import (
"fmt"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/urfave/cli"
)
@ -15,9 +15,9 @@ var VersionCommand = cli.Command{
}
func versionAction(ctx *cli.Context) error {
app := context.NewContext(ctx)
conf := config.NewConfig(ctx)
fmt.Println(app.Version())
fmt.Println(conf.Version())
return nil
}

View file

@ -1,4 +1,4 @@
package context
package config
// HTTP client / Web UI config values
type ClientConfig map[string]interface{}

View file

@ -1,4 +1,4 @@
package context
package config
import (
"errors"
@ -8,16 +8,16 @@ import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/models"
"github.com/photoprism/photoprism/internal/tidb"
"github.com/photoprism/photoprism/internal/util"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
type Context struct {
type Config struct {
db *gorm.DB
config *Config
config *Params
}
func initLogger(debug bool) {
@ -33,10 +33,10 @@ func initLogger(debug bool) {
}
}
func NewContext(ctx *cli.Context) *Context {
func NewConfig(ctx *cli.Context) *Config {
initLogger(ctx.GlobalBool("debug"))
c := &Context{config: NewConfig(ctx)}
c := &Config{config: NewParams(ctx)}
log.SetLevel(c.LogLevel())
@ -48,7 +48,7 @@ func NewContext(ctx *cli.Context) *Context {
// ThumbnailsPath
// ImportPath
// ExportPath
func (c *Context) CreateDirectories() error {
func (c *Config) CreateDirectories() error {
if err := os.MkdirAll(c.OriginalsPath(), os.ModePerm); err != nil {
return err
}
@ -83,7 +83,7 @@ func (c *Context) CreateDirectories() error {
// connectToDatabase establishes a database connection.
// When used with the internal driver, it may create a new database server instance.
// It tries to do this 12 times with a 5 second sleep interval in between.
func (c *Context) connectToDatabase() error {
func (c *Config) connectToDatabase() error {
dbDriver := c.DatabaseDriver()
dbDsn := c.DatabaseDsn()
@ -143,32 +143,32 @@ func (c *Context) connectToDatabase() error {
}
// Name returns the application name.
func (c *Context) Name() string {
func (c *Config) Name() string {
return c.config.Name
}
// Version returns the application version.
func (c *Context) Version() string {
func (c *Config) Version() string {
return c.config.Version
}
// Copyright returns the application copyright.
func (c *Context) Copyright() string {
func (c *Config) Copyright() string {
return c.config.Copyright
}
// Debug returns true if Debug mode is on.
func (c *Context) Debug() bool {
func (c *Config) Debug() bool {
return c.config.Debug
}
// ReadOnly returns true if photo directories are write protected.
func (c *Context) ReadOnly() bool {
func (c *Config) ReadOnly() bool {
return c.config.ReadOnly
}
// LogLevel returns the logrus log level.
func (c *Context) LogLevel() log.Level {
func (c *Config) LogLevel() log.Level {
if c.Debug() {
c.config.LogLevel = "debug"
}
@ -181,22 +181,22 @@ func (c *Context) LogLevel() log.Level {
}
// TestConfigFile returns the config file name.
func (c *Context) ConfigFile() string {
func (c *Config) ConfigFile() string {
return c.config.ConfigFile
}
// SqlServerHost returns the built-in SQL server host name or IP address (empty for all interfaces).
func (c *Context) SqlServerHost() string {
func (c *Config) SqlServerHost() string {
return c.config.SqlServerHost
}
// SqlServerPort returns the built-in SQL server port.
func (c *Context) SqlServerPort() uint {
func (c *Config) SqlServerPort() uint {
return c.config.SqlServerPort
}
// SqlServerPath returns the database storage path for TiDB.
func (c *Context) SqlServerPath() string {
func (c *Config) SqlServerPath() string {
if c.config.SqlServerPath != "" {
return c.config.SqlServerPath
}
@ -205,12 +205,12 @@ func (c *Context) SqlServerPath() string {
}
// SqlServerPassword returns the password for the built-in database server.
func (c *Context) SqlServerPassword() string {
func (c *Config) SqlServerPassword() string {
return c.config.SqlServerPassword
}
// HttpServerHost returns the built-in HTTP server host name or IP address (empty for all interfaces).
func (c *Context) HttpServerHost() string {
func (c *Config) HttpServerHost() string {
if c.config.HttpServerHost == "" {
return "0.0.0.0"
}
@ -219,37 +219,37 @@ func (c *Context) HttpServerHost() string {
}
// HttpServerPort returns the built-in HTTP server port.
func (c *Context) HttpServerPort() int {
func (c *Config) HttpServerPort() int {
return c.config.HttpServerPort
}
// HttpServerMode returns the server mode.
func (c *Context) HttpServerMode() string {
func (c *Config) HttpServerMode() string {
return c.config.HttpServerMode
}
// HttpServerPassword returns the password for the user interface (optional).
func (c *Context) HttpServerPassword() string {
func (c *Config) HttpServerPassword() string {
return c.config.HttpServerPassword
}
// OriginalsPath returns the originals.
func (c *Context) OriginalsPath() string {
func (c *Config) OriginalsPath() string {
return c.config.OriginalsPath
}
// ImportPath returns the import directory.
func (c *Context) ImportPath() string {
func (c *Config) ImportPath() string {
return c.config.ImportPath
}
// ExportPath returns the export directory.
func (c *Context) ExportPath() string {
func (c *Config) ExportPath() string {
return c.config.ExportPath
}
// DarktableCli returns the darktable-cli binary file name.
func (c *Context) DarktableCli() string {
func (c *Config) DarktableCli() string {
if c.config.DarktableCli == "" {
return "/usr/bin/darktable-cli"
}
@ -257,7 +257,7 @@ func (c *Context) DarktableCli() string {
}
// DatabaseDriver returns the database driver name.
func (c *Context) DatabaseDriver() string {
func (c *Config) DatabaseDriver() string {
if c.config.DatabaseDriver == "" {
return DbTiDB
}
@ -266,7 +266,7 @@ func (c *Context) DatabaseDriver() string {
}
// DatabaseDsn returns the database data source name (DSN).
func (c *Context) DatabaseDsn() string {
func (c *Config) DatabaseDsn() string {
if c.config.DatabaseDsn == "" {
return "root:photoprism@tcp(localhost:4000)/photoprism?parseTime=true"
}
@ -275,52 +275,52 @@ func (c *Context) DatabaseDsn() string {
}
// CachePath returns the path to the cache.
func (c *Context) CachePath() string {
func (c *Config) CachePath() string {
return c.config.CachePath
}
// ThumbnailsPath returns the path to the cached thumbnails.
func (c *Context) ThumbnailsPath() string {
func (c *Config) ThumbnailsPath() string {
return c.CachePath() + "/thumbnails"
}
// AssetsPath returns the path to the assets.
func (c *Context) AssetsPath() string {
func (c *Config) AssetsPath() string {
return c.config.AssetsPath
}
// TensorFlowModelPath returns the tensorflow model path.
func (c *Context) TensorFlowModelPath() string {
func (c *Config) TensorFlowModelPath() string {
return c.AssetsPath() + "/tensorflow"
}
// ServerPath returns the server assets path (public files, favicons, templates,...).
func (c *Context) ServerPath() string {
func (c *Config) ServerPath() string {
return c.AssetsPath() + "/server"
}
// HttpTemplatesPath returns the server templates path.
func (c *Context) HttpTemplatesPath() string {
func (c *Config) HttpTemplatesPath() string {
return c.ServerPath() + "/templates"
}
// HttpFaviconsPath returns the favicons path.
func (c *Context) HttpFaviconsPath() string {
func (c *Config) HttpFaviconsPath() string {
return c.HttpPublicPath() + "/favicons"
}
// HttpPublicPath returns the public server path (//server/assets/*).
func (c *Context) HttpPublicPath() string {
func (c *Config) HttpPublicPath() string {
return c.ServerPath() + "/public"
}
// HttpPublicBuildPath returns the public build path (//server/assets/build/*).
func (c *Context) HttpPublicBuildPath() string {
func (c *Config) HttpPublicBuildPath() string {
return c.HttpPublicPath() + "/build"
}
// Db returns the db connection.
func (c *Context) Db() *gorm.DB {
func (c *Config) Db() *gorm.DB {
if c.db == nil {
if err := c.connectToDatabase(); err != nil {
log.Fatal(err)
@ -331,7 +331,7 @@ func (c *Context) Db() *gorm.DB {
}
// CloseDb closes the db connection (if any).
func (c *Context) CloseDb() error {
func (c *Config) CloseDb() error {
if c.db != nil {
if err := c.db.Close(); err == nil {
c.db = nil
@ -344,7 +344,7 @@ func (c *Context) CloseDb() error {
}
// MigrateDb will start a migration process.
func (c *Context) MigrateDb() {
func (c *Config) MigrateDb() {
db := c.Db()
db.AutoMigrate(
@ -361,7 +361,7 @@ func (c *Context) MigrateDb() {
}
// ClientConfig returns a loaded and set configuration entity.
func (c *Context) ClientConfig() ClientConfig {
func (c *Config) ClientConfig() ClientConfig {
db := c.Db()
var cameras []*models.Camera
@ -377,8 +377,8 @@ func (c *Context) ClientConfig() ClientConfig {
db.Where("deleted_at IS NULL").Limit(1000).Order("camera_model").Find(&cameras)
jsHash := fsutil.Hash(c.HttpPublicBuildPath() + "/app.js")
cssHash := fsutil.Hash(c.HttpPublicBuildPath() + "/app.css")
jsHash := util.Hash(c.HttpPublicBuildPath() + "/app.js")
cssHash := util.Hash(c.HttpPublicBuildPath() + "/app.css")
result := ClientConfig{
"name": c.Name(),
@ -395,7 +395,7 @@ func (c *Context) ClientConfig() ClientConfig {
return result
}
func (c *Context) Shutdown() {
func (c *Config) Shutdown() {
if err := c.CloseDb(); err != nil {
log.Errorf("could not close database connection: %s", err)
} else {

View file

@ -0,0 +1,23 @@
package config
import (
"testing"
"github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert"
)
func TestNewConfig(t *testing.T) {
ctx := CliTestContext()
assert.True(t, ctx.IsSet("assets-path"))
assert.False(t, ctx.Bool("debug"))
c := NewConfig(ctx)
assert.IsType(t, new(Config), c)
assert.Equal(t, util.ExpandedFilename("../../assets"), c.AssetsPath())
assert.False(t, c.Debug())
assert.False(t, c.ReadOnly())
}

View file

@ -1,8 +1,8 @@
/*
Package context contains CLI context related config functionality.
Package config contains CLI config related config functionality.
Additional information can be found in our Developer Guide:
https://github.com/photoprism/photoprism/wiki
*/
package context
package config

View file

@ -1,4 +1,4 @@
package context
package config
import "github.com/urfave/cli"

View file

@ -1,4 +1,4 @@
package context
package config
import (
"errors"
@ -8,7 +8,7 @@ import (
_ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/util"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
"gopkg.in/yaml.v2"
@ -19,7 +19,7 @@ const (
DbMySQL = "mysql"
)
// Config provides a struct in which application configuration is stored.
// Params provides a struct in which application configuration is stored.
// Application code must use functions to get config values, for two reasons:
//
// 1. Some values are computed and we don't want to leak implementation details (aims at reducing refactoring overhead).
@ -27,7 +27,7 @@ const (
// 2. Paths might actually be dynamic later (if we build a multi-user version).
//
// See https://github.com/photoprism/photoprism/issues/50#issuecomment-433856358
type Config struct {
type Params struct {
Name string
Version string
Copyright string
@ -53,20 +53,20 @@ type Config struct {
DatabaseDsn string `yaml:"database-dsn" flag:"database-dsn"`
}
// NewConfig() creates a new configuration entity by using two methods:
// NewParams() creates a new configuration entity by using two methods:
//
// 1. SetValuesFromFile: This will initialize values from a yaml config file.
//
// 2. SetValuesFromCliContext: Which comes after SetValuesFromFile and overrides
// any previous values giving an option two override file configs through the CLI.
func NewConfig(ctx *cli.Context) *Config {
c := &Config{}
func NewParams(ctx *cli.Context) *Params {
c := &Params{}
c.Name = ctx.App.Name
c.Copyright = ctx.App.Copyright
c.Version = ctx.App.Version
if err := c.SetValuesFromFile(fsutil.ExpandedFilename(ctx.GlobalString("config-file"))); err != nil {
if err := c.SetValuesFromFile(util.ExpandedFilename(ctx.GlobalString("config-file"))); err != nil {
log.Debug(err)
}
@ -79,19 +79,19 @@ func NewConfig(ctx *cli.Context) *Config {
return c
}
func (c *Config) expandFilenames() {
c.AssetsPath = fsutil.ExpandedFilename(c.AssetsPath)
c.CachePath = fsutil.ExpandedFilename(c.CachePath)
c.OriginalsPath = fsutil.ExpandedFilename(c.OriginalsPath)
c.ImportPath = fsutil.ExpandedFilename(c.ImportPath)
c.ExportPath = fsutil.ExpandedFilename(c.ExportPath)
c.DarktableCli = fsutil.ExpandedFilename(c.DarktableCli)
c.SqlServerPath = fsutil.ExpandedFilename(c.SqlServerPath)
func (c *Params) expandFilenames() {
c.AssetsPath = util.ExpandedFilename(c.AssetsPath)
c.CachePath = util.ExpandedFilename(c.CachePath)
c.OriginalsPath = util.ExpandedFilename(c.OriginalsPath)
c.ImportPath = util.ExpandedFilename(c.ImportPath)
c.ExportPath = util.ExpandedFilename(c.ExportPath)
c.DarktableCli = util.ExpandedFilename(c.DarktableCli)
c.SqlServerPath = util.ExpandedFilename(c.SqlServerPath)
}
// SetValuesFromFile uses a yaml config file to initiate the configuration entity.
func (c *Config) SetValuesFromFile(fileName string) error {
if !fsutil.Exists(fileName) {
func (c *Params) SetValuesFromFile(fileName string) error {
if !util.Exists(fileName) {
return errors.New(fmt.Sprintf("config file not found: \"%s\"", fileName))
}
@ -106,7 +106,7 @@ func (c *Config) SetValuesFromFile(fileName string) error {
// SetValuesFromCliContext uses values from the CLI to setup configuration overrides
// for the entity.
func (c *Config) SetValuesFromCliContext(ctx *cli.Context) error {
func (c *Params) SetValuesFromCliContext(ctx *cli.Context) error {
v := reflect.ValueOf(c).Elem()
// Iterate through all config fields

View file

@ -1,29 +1,29 @@
package context
package config
import (
"testing"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert"
)
func TestNewConfig(t *testing.T) {
func TestNewParams(t *testing.T) {
ctx := CliTestContext()
assert.True(t, ctx.IsSet("assets-path"))
assert.False(t, ctx.Bool("debug"))
c := NewConfig(ctx)
c := NewParams(ctx)
assert.IsType(t, new(Config), c)
assert.IsType(t, new(Params), c)
assert.Equal(t, fsutil.ExpandedFilename("../../assets"), c.AssetsPath)
assert.Equal(t, util.ExpandedFilename("../../assets"), c.AssetsPath)
assert.False(t, c.Debug)
assert.False(t, c.ReadOnly)
}
func TestConfig_SetValuesFromFile(t *testing.T) {
c := NewConfig(CliTestContext())
func TestParams_SetValuesFromFile(t *testing.T) {
c := NewParams(CliTestContext())
err := c.SetValuesFromFile("testdata/config.yml")

View file

@ -1,4 +1,4 @@
package context
package config
import (
"flag"
@ -8,7 +8,7 @@ import (
_ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/util"
"github.com/urfave/cli"
log "github.com/sirupsen/logrus"
@ -20,18 +20,18 @@ const (
TestDataHash = "1a59b358b80221ab3e76efb683ad72402f0b0844"
)
var testContext *Context
var testConfig *Config
func testDataPath(assetsPath string) string {
return assetsPath + "/testdata"
}
func NewTestConfig() *Config {
assetsPath := fsutil.ExpandedFilename("../../assets")
func NewTestParams() *Params {
assetsPath := util.ExpandedFilename("../../assets")
testDataPath := testDataPath(assetsPath)
c := &Config{
c := &Params{
DarktableCli: "/usr/bin/darktable-cli",
AssetsPath: assetsPath,
CachePath: testDataPath + "/cache",
@ -45,27 +45,27 @@ func NewTestConfig() *Config {
return c
}
func TestContext() *Context {
if testContext == nil {
testContext = NewTestContext()
func TestConfig() *Config {
if testConfig == nil {
testConfig = NewTestConfig()
}
return testContext
return testConfig
}
func NewTestContext() *Context {
func NewTestConfig() *Config {
log.SetLevel(log.DebugLevel)
c := &Context{config: NewTestConfig()}
c := &Config{config: NewTestParams()}
c.MigrateDb()
return c
}
// Returns example cli context for testing
// Returns example cli config for testing
func CliTestContext() *cli.Context {
config := NewTestConfig()
config := NewTestParams()
globalSet := flag.NewFlagSet("test", 0)
globalSet.Bool("debug", false, "doc")
@ -86,16 +86,16 @@ func CliTestContext() *cli.Context {
return c
}
func (c *Context) RemoveTestData(t *testing.T) {
func (c *Config) RemoveTestData(t *testing.T) {
os.RemoveAll(c.ImportPath())
os.RemoveAll(c.ExportPath())
os.RemoveAll(c.OriginalsPath())
os.RemoveAll(c.CachePath())
}
func (c *Context) DownloadTestData(t *testing.T) {
if fsutil.Exists(TestDataZip) {
hash := fsutil.Hash(TestDataZip)
func (c *Config) DownloadTestData(t *testing.T) {
if util.Exists(TestDataZip) {
hash := util.Hash(TestDataZip)
if hash != TestDataHash {
os.Remove(TestDataZip)
@ -103,22 +103,22 @@ func (c *Context) DownloadTestData(t *testing.T) {
}
}
if !fsutil.Exists(TestDataZip) {
if !util.Exists(TestDataZip) {
fmt.Printf("downloading latest test data zip file from %s\n", TestDataURL)
if err := fsutil.Download(TestDataZip, TestDataURL); err != nil {
if err := util.Download(TestDataZip, TestDataURL); err != nil {
fmt.Printf("Download failed: %s\n", err.Error())
}
}
}
func (c *Context) UnzipTestData(t *testing.T) {
if _, err := fsutil.Unzip(TestDataZip, testDataPath(c.AssetsPath())); err != nil {
func (c *Config) UnzipTestData(t *testing.T) {
if _, err := util.Unzip(TestDataZip, testDataPath(c.AssetsPath())); err != nil {
t.Logf("could not unzip test data: %s\n", err.Error())
}
}
func (c *Context) InitializeTestData(t *testing.T) {
func (c *Config) InitializeTestData(t *testing.T) {
t.Log("initializing test data")
c.RemoveTestData(t)

View file

@ -1,10 +1,10 @@
package context
package config
import (
"testing"
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
)
@ -15,24 +15,24 @@ func TestTestCliContext(t *testing.T) {
assert.IsType(t, new(cli.Context), result)
}
func TestTestContext(t *testing.T) {
result := TestContext()
func TestTestConfig(t *testing.T) {
result := TestConfig()
assert.IsType(t, new(Context), result)
assert.IsType(t, new(Config), result)
}
func TestNewTestParams(t *testing.T) {
c := NewTestParams()
assert.IsType(t, new(Params), c)
assert.Equal(t, util.ExpandedFilename("../../assets"), c.AssetsPath)
assert.False(t, c.Debug)
}
func TestNewTestConfig(t *testing.T) {
c := NewTestConfig()
assert.IsType(t, new(Config), c)
assert.Equal(t, fsutil.ExpandedFilename("../../assets"), c.AssetsPath)
assert.False(t, c.Debug)
}
func TestNewTestContext_Db(t *testing.T) {
c := NewTestContext()
db := c.Db()
assert.IsType(t, &gorm.DB{}, db)

View file

@ -1,23 +0,0 @@
package context
import (
"testing"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/stretchr/testify/assert"
)
func TestNewContext(t *testing.T) {
ctx := CliTestContext()
assert.True(t, ctx.IsSet("assets-path"))
assert.False(t, ctx.Bool("debug"))
c := NewContext(ctx)
assert.IsType(t, new(Context), c)
assert.Equal(t, fsutil.ExpandedFilename("../../assets"), c.AssetsPath())
assert.False(t, c.Debug())
assert.False(t, c.ReadOnly())
}

View file

@ -6,7 +6,7 @@ import (
"strings"
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert"
)
@ -80,7 +80,7 @@ func TestMediaFile_Colors_Testdata(t *testing.T) {
}
func TestMediaFile_Colors(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)

View file

@ -4,13 +4,13 @@ import (
"os"
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert"
)
func TestNewConverter(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
converter := NewConverter(ctx.DarktableCli())
@ -22,7 +22,7 @@ func TestConverter_ConvertToJpeg(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -30,7 +30,7 @@ func TestConverter_ConvertToJpeg(t *testing.T) {
jpegFilename := ctx.ImportPath() + "/iphone/IMG_6788.JPG"
assert.Truef(t, fsutil.Exists(jpegFilename), "file does not exist: %s", jpegFilename)
assert.Truef(t, util.Exists(jpegFilename), "file does not exist: %s", jpegFilename)
t.Logf("Testing RAW to JPEG converter with %s", jpegFilename)
@ -62,7 +62,7 @@ func TestConverter_ConvertToJpeg(t *testing.T) {
imageRaw, _ := converter.ConvertToJpeg(rawMediaFile)
assert.True(t, fsutil.Exists(ctx.ImportPath()+"/raw/IMG_1435.jpg"), "Jpeg file was not found - is Darktable installed?")
assert.True(t, util.Exists(ctx.ImportPath()+"/raw/IMG_1435.jpg"), "Jpeg file was not found - is Darktable installed?")
assert.NotEqual(t, rawFilemame, imageRaw.filename)
@ -78,7 +78,7 @@ func TestConverter_ConvertAll(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -88,7 +88,7 @@ func TestConverter_ConvertAll(t *testing.T) {
jpegFilename := ctx.ImportPath() + "/raw/IMG_1435.jpg"
assert.True(t, fsutil.Exists(jpegFilename), "Jpeg file was not found - is Darktable installed?")
assert.True(t, util.Exists(jpegFilename), "Jpeg file was not found - is Darktable installed?")
image, err := NewMediaFile(jpegFilename)
@ -104,15 +104,15 @@ func TestConverter_ConvertAll(t *testing.T) {
existingJpegFilename := ctx.ImportPath() + "/raw/20140717_154212_1EC48F8489.jpg"
oldHash := fsutil.Hash(existingJpegFilename)
oldHash := util.Hash(existingJpegFilename)
os.Remove(existingJpegFilename)
converter.ConvertAll(ctx.ImportPath())
newHash := fsutil.Hash(existingJpegFilename)
newHash := util.Hash(existingJpegFilename)
assert.True(t, fsutil.Exists(existingJpegFilename), "Jpeg file was not found - is Darktable installed?")
assert.True(t, util.Exists(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")
}

View file

@ -3,12 +3,12 @@ package photoprism
import (
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert"
)
func TestMediaFile_ExifData(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -30,7 +30,7 @@ func TestMediaFile_ExifData_Slow(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)

View file

@ -11,7 +11,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/util"
)
// Importer todo: Fill me.
@ -149,8 +149,8 @@ func (i *Importer) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
result := pathName + "/" + canonicalName + fileExtension
for fsutil.Exists(result) {
if mediaFile.Hash() == fsutil.Hash(result) {
for util.Exists(result) {
if mediaFile.Hash() == util.Hash(result) {
return result, fmt.Errorf("file already exists: %s", result)
}

View file

@ -3,12 +3,12 @@ package photoprism
import (
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert"
)
func TestNewImporter(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
tensorFlow := NewTensorFlow(ctx.TensorFlowModelPath())
@ -22,7 +22,7 @@ func TestNewImporter(t *testing.T) {
}
func TestImporter_DestinationFilename(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -50,7 +50,7 @@ func TestImporter_ImportPhotosFromDirectory(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)

View file

@ -150,7 +150,7 @@ func (i *Indexer) indexMediaFile(mediaFile *MediaFile) string {
photo.PhotoTitle = fmt.Sprintf("%s / %s", strings.Title(photo.Tags[0].TagLabel), mediaFile.DateCreated().Format("2006"))
} else if photo.Country != nil && photo.Country.CountryName != "" {
photo.PhotoTitle = fmt.Sprintf("%s / %s", strings.Title(photo.Country.CountryName), mediaFile.DateCreated().Format("2006"))
} else if photo.Camera.String() != "" && photo.Camera.String() != "Unknown" {
} else if photo.Camera.String() != "" && photo.Camera.String() != "Unknown" {
photo.PhotoTitle = fmt.Sprintf("%s / %s", photo.Camera, mediaFile.DateCreated().Format("January 2006"))
} else {
var daytimeString string

View file

@ -18,8 +18,8 @@ import (
log "github.com/sirupsen/logrus"
"github.com/djherbis/times"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/models"
"github.com/photoprism/photoprism/internal/util"
)
const (
@ -119,7 +119,7 @@ type MediaFile struct {
// NewMediaFile returns a new MediaFile.
func NewMediaFile(filename string) (*MediaFile, error) {
if !fsutil.Exists(filename) {
if !util.Exists(filename) {
return nil, fmt.Errorf("file does not exist: %s", filename)
}
@ -279,7 +279,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 = fsutil.Hash(m.Filename())
m.hash = util.Hash(m.Filename())
}
return m.hash
@ -306,7 +306,7 @@ func (m *MediaFile) RelatedFiles() (result MediaFiles, mainFile *MediaFile, err
return result, nil, err
}
if editedFilename := m.EditedFilename(); editedFilename != "" && fsutil.Exists(editedFilename) {
if editedFilename := m.EditedFilename(); editedFilename != "" && util.Exists(editedFilename) {
matches = append(matches, editedFilename)
}
@ -406,7 +406,7 @@ func (m *MediaFile) openFile() (*os.File, error) {
// Exists checks if a mediafile exists by filename.
func (m *MediaFile) Exists() bool {
return fsutil.Exists(m.Filename())
return util.Exists(m.Filename())
}
// Remove a mediafile.
@ -514,7 +514,7 @@ func (m *MediaFile) Jpeg() (*MediaFile, error) {
jpegFilename := m.CanonicalNameFromFileWithDirectory() + ".jpg"
if !fsutil.Exists(jpegFilename) {
if !util.Exists(jpegFilename) {
return nil, fmt.Errorf("jpeg file does not exist: %s", jpegFilename)
}

View file

@ -3,12 +3,12 @@ package photoprism
import (
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert"
)
func TestMediaFile_RelatedFiles(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -38,7 +38,7 @@ func TestMediaFile_RelatedFiles(t *testing.T) {
}
func TestMediaFile_RelatedFiles_Ordering(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -59,7 +59,7 @@ func TestMediaFile_RelatedFiles_Ordering(t *testing.T) {
}
func TestMediaFile_EditedFilename(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -79,7 +79,7 @@ func TestMediaFile_EditedFilename(t *testing.T) {
}
func TestMediaFile_MimeType(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -93,7 +93,7 @@ func TestMediaFile_MimeType(t *testing.T) {
}
func TestMediaFile_Exists(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
mediaFile, err := NewMediaFile(ctx.ImportPath() + "/iphone/IMG_6788.JPG")
assert.Nil(t, err)

View file

@ -3,12 +3,12 @@ package photoprism
import (
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/forms"
)
func TestSearch_Photos_Query(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.CreateDirectories()
@ -41,7 +41,7 @@ func TestSearch_Photos_Query(t *testing.T) {
}
func TestSearch_Photos_Camera(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.CreateDirectories()

View file

@ -147,7 +147,9 @@ func (t *TensorFlow) findBestLabels(probabilities []float32) []TensorFlowLabel {
break
}
if p < 0.08 { continue }
if p < 0.08 {
continue
}
result = append(result, TensorFlowLabel{Label: t.labels[i], Probability: p})
}

View file

@ -4,12 +4,12 @@ import (
"io/ioutil"
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert"
)
func TestTensorFlow_GetImageTagsFromFile(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -42,7 +42,7 @@ func TestTensorFlow_GetImageTags(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)
@ -74,7 +74,7 @@ func TestTensorFlow_GetImageTags_Dog(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.InitializeTestData(t)

View file

@ -9,7 +9,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/disintegration/imaging"
"github.com/photoprism/photoprism/internal/fsutil"
"github.com/photoprism/photoprism/internal/util"
)
// CreateThumbnailsFromOriginals create thumbnails.
@ -58,7 +58,7 @@ func (m *MediaFile) Thumbnail(path string, size int) (result *MediaFile, err err
thumbnailFilename := fmt.Sprintf("%s/%s_%dpx.jpg", thumbnailPath, canonicalName, size)
if fsutil.Exists(thumbnailFilename) {
if util.Exists(thumbnailFilename) {
return NewMediaFile(thumbnailFilename)
}
@ -97,7 +97,7 @@ func (m *MediaFile) SquareThumbnail(path string, size int) (result *MediaFile, e
thumbnailFilename := fmt.Sprintf("%s/%s_square_%dpx.jpg", thumbnailPath, canonicalName, size)
if fsutil.Exists(thumbnailFilename) {
if util.Exists(thumbnailFilename) {
return NewMediaFile(thumbnailFilename)
}

View file

@ -3,12 +3,12 @@ package photoprism
import (
"testing"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert"
)
func TestMediaFile_Thumbnail(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.CreateDirectories()
@ -25,7 +25,7 @@ func TestMediaFile_Thumbnail(t *testing.T) {
}
func TestMediaFile_SquareThumbnail(t *testing.T) {
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.CreateDirectories()
@ -46,7 +46,7 @@ func TestCreateThumbnailsFromOriginals(t *testing.T) {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext()
ctx := config.TestConfig()
ctx.CreateDirectories()

View file

@ -5,27 +5,27 @@ import (
"github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/api"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
)
func registerRoutes(router *gin.Engine, ctx *context.Context) {
func registerRoutes(router *gin.Engine, conf *config.Config) {
// Favicon
router.StaticFile("/favicon.ico", ctx.HttpFaviconsPath()+"/favicon.ico")
router.StaticFile("/favicon.ico", conf.HttpFaviconsPath()+"/favicon.ico")
// Static assets like js and css files
router.Static("/assets", ctx.HttpPublicPath())
router.Static("/assets", conf.HttpPublicPath())
// JSON-REST API Version 1
v1 := router.Group("/api/v1")
{
api.GetPhotos(v1, ctx)
api.GetThumbnail(v1, ctx)
api.LikePhoto(v1, ctx)
api.DislikePhoto(v1, ctx)
api.GetPhotos(v1, conf)
api.GetThumbnail(v1, conf)
api.LikePhoto(v1, conf)
api.DislikePhoto(v1, conf)
}
// Default HTML page (client-side routing implemented via Vue.js)
router.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", ctx.ClientConfig())
c.HTML(http.StatusOK, "index.tmpl", conf.ClientConfig())
})
}

View file

@ -9,15 +9,15 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/context"
"github.com/photoprism/photoprism/internal/config"
log "github.com/sirupsen/logrus"
)
// Start the REST API server using the configuration provided
func Start(ctx *context.Context) {
if ctx.HttpServerMode() != "" {
gin.SetMode(ctx.HttpServerMode())
} else if ctx.Debug() == false {
func Start(conf *config.Config) {
if conf.HttpServerMode() != "" {
gin.SetMode(conf.HttpServerMode())
} else if conf.Debug() == false {
gin.SetMode(gin.ReleaseMode)
}
@ -25,19 +25,19 @@ func Start(ctx *context.Context) {
router.Use(gin.Logger(), gin.Recovery())
// Set template directory
router.LoadHTMLGlob(ctx.HttpTemplatesPath() + "/*")
router.LoadHTMLGlob(conf.HttpTemplatesPath() + "/*")
registerRoutes(router, ctx)
registerRoutes(router, conf)
server := &http.Server{
Addr: fmt.Sprintf("%s:%d", ctx.HttpServerHost(), ctx.HttpServerPort()),
Addr: fmt.Sprintf("%s:%d", conf.HttpServerHost(), conf.HttpServerPort()),
Handler: router,
}
quit := make(chan os.Signal)
/*
TODO: Use context for graceful shutdown of all services and add HTTP / TiDB server tests
TODO: Use config for graceful shutdown of all services and add HTTP / TiDB server tests
See
- https://github.com/gin-gonic/gin/blob/dfe37ea6f1b9127be4cff4822a1308b4349444e0/examples/graceful-shutdown/graceful-shutdown/server.go
@ -50,7 +50,7 @@ func Start(ctx *context.Context) {
<-quit
log.Info("received interrupt signal - shutting down")
ctx.Shutdown()
conf.Shutdown()
if err := server.Close(); err != nil {
log.Errorf("server close: %s", err)

View file

@ -106,7 +106,7 @@ func Start(path string, port uint, host string, debug bool) {
createServer()
/*
TODO: Use context for graceful shutdown of all services and add HTTP / TiDB server tests
TODO: Use config for graceful shutdown of all services and add HTTP / TiDB server tests
See
- https://github.com/gin-gonic/gin/blob/dfe37ea6f1b9127be4cff4822a1308b4349444e0/examples/graceful-shutdown/graceful-shutdown/server.go

View file

@ -1,4 +1,4 @@
package context
package util
import (
"bytes"

View file

@ -1,4 +1,4 @@
package context
package util
import (
"fmt"

View file

@ -1,8 +1,8 @@
/*
Package context contains filesystem related utility functions.
Package config contains filesystem related utility functions.
Additional information can be found in our Developer Guide:
https://github.com/photoprism/photoprism/wiki
*/
package fsutil
package util

View file

@ -1,4 +1,4 @@
package fsutil
package util
import (
"archive/zip"

View file

@ -1,4 +1,4 @@
package fsutil
package util
import (
"testing"

View file

@ -1,4 +1,4 @@
package fsutil
package util
import (
"crypto/sha1"

View file

@ -1,4 +1,4 @@
package fsutil
package util
import (
"testing"

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB