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" "os"
"github.com/photoprism/photoprism/internal/commands" "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" "github.com/urfave/cli"
) )
@ -17,7 +18,7 @@ func main() {
app.Version = version app.Version = version
app.Copyright = "(c) 2018-2019 The PhotoPrism contributors <hello@photoprism.org>" app.Copyright = "(c) 2018-2019 The PhotoPrism contributors <hello@photoprism.org>"
app.EnableBashCompletion = true app.EnableBashCompletion = true
app.Flags = context.GlobalFlags app.Flags = config.GlobalFlags
app.Commands = []cli.Command{ app.Commands = []cli.Command{
commands.ConfigCommand, commands.ConfigCommand,
@ -31,5 +32,7 @@ func main() {
commands.VersionCommand, 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" "net/http/httptest"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
) )
// API test helper // API test helper
func NewApiTest() (app *gin.Engine, router *gin.RouterGroup, ctx *context.Context) { func NewApiTest() (app *gin.Engine, router *gin.RouterGroup, conf *config.Config) {
ctx = context.TestContext() conf = config.TestConfig()
gin.SetMode(gin.TestMode) gin.SetMode(gin.TestMode)
app = gin.New() app = gin.New()
router = app.Group("/api/v1") router = app.Group("/api/v1")
return app, router, ctx return app, router, conf
} }
// See https://medium.com/@craigchilds94/testing-gin-json-responses-1f258ce3b0b1 // See https://medium.com/@craigchilds94/testing-gin-json-responses-1f258ce3b0b1

View file

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

View file

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

View file

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

View file

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

View file

@ -1,7 +1,7 @@
package commands package commands
import ( import (
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism" "github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -15,17 +15,17 @@ var ConvertCommand = cli.Command{
} }
func convertAction(ctx *cli.Context) error { 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 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") log.Infof("image conversion complete")

View file

@ -6,7 +6,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism" "github.com/photoprism/photoprism/internal/photoprism"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -40,9 +40,9 @@ var exportFlags = []cli.Flag{
} }
func exportAction(ctx *cli.Context) error { 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 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") 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) log.Infof("exporting photos to %s", exportPath)
photoprism.ExportPhotosFromOriginals(originals, app.ThumbnailsPath(), exportPath, size) if err := photoprism.ExportPhotosFromOriginals(originals, conf.ThumbnailsPath(), exportPath, size); err != nil {
log.Error(err)
} else {
log.Infof("photo export complete") log.Infof("photo export complete")
}
return nil return nil
} }

View file

@ -1,7 +1,7 @@
package commands package commands
import ( import (
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism" "github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -15,25 +15,25 @@ var ImportCommand = cli.Command{
} }
func importAction(ctx *cli.Context) error { 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 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") log.Info("photo import complete")

View file

@ -1,7 +1,7 @@
package commands package commands
import ( import (
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism" "github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -15,25 +15,25 @@ var IndexCommand = cli.Command{
} }
func indexAction(ctx *cli.Context) error { 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 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() files := indexer.IndexAll()
log.Infof("indexed %d files", len(files)) log.Infof("indexed %d files", len(files))
app.Shutdown() conf.Shutdown()
return nil return nil
} }

View file

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

View file

@ -3,7 +3,7 @@ package commands
import ( import (
log "github.com/sirupsen/logrus" 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/photoprism/photoprism/internal/server"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -38,21 +38,21 @@ var startFlags = []cli.Flag{
} }
func startAction(ctx *cli.Context) error { 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") log.Fatal("server port must be a positive integer")
} }
if err := app.CreateDirectories(); err != nil { if err := conf.CreateDirectories(); err != nil {
log.Fatal(err) 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 return nil
} }

View file

@ -1,7 +1,7 @@
package commands package commands
import ( import (
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism" "github.com/photoprism/photoprism/internal/photoprism"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -29,13 +29,13 @@ var ThumbnailsCommand = cli.Command{
} }
func thumbnailsAction(ctx *cli.Context) error { 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 return err
} }
log.Infof("creating thumbnails in \"%s\"", app.ThumbnailsPath()) log.Infof("creating thumbnails in \"%s\"", conf.ThumbnailsPath())
sizes := ctx.IntSlice("size") sizes := ctx.IntSlice("size")
@ -49,7 +49,7 @@ func thumbnailsAction(ctx *cli.Context) error {
} }
for _, size := range sizes { 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") log.Info("thumbnails created")

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
package context package config
import ( import (
"errors" "errors"
@ -8,7 +8,7 @@ import (
_ "github.com/jinzhu/gorm/dialects/mysql" _ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/sqlite" _ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/photoprism/photoprism/internal/fsutil" "github.com/photoprism/photoprism/internal/util"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@ -19,7 +19,7 @@ const (
DbMySQL = "mysql" 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: // 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). // 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). // 2. Paths might actually be dynamic later (if we build a multi-user version).
// //
// See https://github.com/photoprism/photoprism/issues/50#issuecomment-433856358 // See https://github.com/photoprism/photoprism/issues/50#issuecomment-433856358
type Config struct { type Params struct {
Name string Name string
Version string Version string
Copyright string Copyright string
@ -53,20 +53,20 @@ type Config struct {
DatabaseDsn string `yaml:"database-dsn" flag:"database-dsn"` 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. // 1. SetValuesFromFile: This will initialize values from a yaml config file.
// //
// 2. SetValuesFromCliContext: Which comes after SetValuesFromFile and overrides // 2. SetValuesFromCliContext: Which comes after SetValuesFromFile and overrides
// any previous values giving an option two override file configs through the CLI. // any previous values giving an option two override file configs through the CLI.
func NewConfig(ctx *cli.Context) *Config { func NewParams(ctx *cli.Context) *Params {
c := &Config{} c := &Params{}
c.Name = ctx.App.Name c.Name = ctx.App.Name
c.Copyright = ctx.App.Copyright c.Copyright = ctx.App.Copyright
c.Version = ctx.App.Version 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) log.Debug(err)
} }
@ -79,19 +79,19 @@ func NewConfig(ctx *cli.Context) *Config {
return c return c
} }
func (c *Config) expandFilenames() { func (c *Params) expandFilenames() {
c.AssetsPath = fsutil.ExpandedFilename(c.AssetsPath) c.AssetsPath = util.ExpandedFilename(c.AssetsPath)
c.CachePath = fsutil.ExpandedFilename(c.CachePath) c.CachePath = util.ExpandedFilename(c.CachePath)
c.OriginalsPath = fsutil.ExpandedFilename(c.OriginalsPath) c.OriginalsPath = util.ExpandedFilename(c.OriginalsPath)
c.ImportPath = fsutil.ExpandedFilename(c.ImportPath) c.ImportPath = util.ExpandedFilename(c.ImportPath)
c.ExportPath = fsutil.ExpandedFilename(c.ExportPath) c.ExportPath = util.ExpandedFilename(c.ExportPath)
c.DarktableCli = fsutil.ExpandedFilename(c.DarktableCli) c.DarktableCli = util.ExpandedFilename(c.DarktableCli)
c.SqlServerPath = fsutil.ExpandedFilename(c.SqlServerPath) c.SqlServerPath = util.ExpandedFilename(c.SqlServerPath)
} }
// SetValuesFromFile uses a yaml config file to initiate the configuration entity. // SetValuesFromFile uses a yaml config file to initiate the configuration entity.
func (c *Config) SetValuesFromFile(fileName string) error { func (c *Params) SetValuesFromFile(fileName string) error {
if !fsutil.Exists(fileName) { if !util.Exists(fileName) {
return errors.New(fmt.Sprintf("config file not found: \"%s\"", 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 // SetValuesFromCliContext uses values from the CLI to setup configuration overrides
// for the entity. // for the entity.
func (c *Config) SetValuesFromCliContext(ctx *cli.Context) error { func (c *Params) SetValuesFromCliContext(ctx *cli.Context) error {
v := reflect.ValueOf(c).Elem() v := reflect.ValueOf(c).Elem()
// Iterate through all config fields // Iterate through all config fields

View file

@ -1,29 +1,29 @@
package context package config
import ( import (
"testing" "testing"
"github.com/photoprism/photoprism/internal/fsutil" "github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestNewConfig(t *testing.T) { func TestNewParams(t *testing.T) {
ctx := CliTestContext() ctx := CliTestContext()
assert.True(t, ctx.IsSet("assets-path")) assert.True(t, ctx.IsSet("assets-path"))
assert.False(t, ctx.Bool("debug")) 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.Debug)
assert.False(t, c.ReadOnly) assert.False(t, c.ReadOnly)
} }
func TestConfig_SetValuesFromFile(t *testing.T) { func TestParams_SetValuesFromFile(t *testing.T) {
c := NewConfig(CliTestContext()) c := NewParams(CliTestContext())
err := c.SetValuesFromFile("testdata/config.yml") err := c.SetValuesFromFile("testdata/config.yml")

View file

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

View file

@ -1,10 +1,10 @@
package context package config
import ( import (
"testing" "testing"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/internal/fsutil" "github.com/photoprism/photoprism/internal/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -15,24 +15,24 @@ func TestTestCliContext(t *testing.T) {
assert.IsType(t, new(cli.Context), result) assert.IsType(t, new(cli.Context), result)
} }
func TestTestContext(t *testing.T) { func TestTestConfig(t *testing.T) {
result := TestContext() 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) { func TestNewTestConfig(t *testing.T) {
c := NewTestConfig() 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() db := c.Db()
assert.IsType(t, &gorm.DB{}, 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" "strings"
"testing" "testing"
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -80,7 +80,7 @@ func TestMediaFile_Colors_Testdata(t *testing.T) {
} }
func TestMediaFile_Colors(t *testing.T) { func TestMediaFile_Colors(t *testing.T) {
ctx := context.TestContext() ctx := config.TestConfig()
ctx.InitializeTestData(t) ctx.InitializeTestData(t)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,7 +9,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
"github.com/photoprism/photoprism/internal/fsutil" "github.com/photoprism/photoprism/internal/util"
) )
// CreateThumbnailsFromOriginals create thumbnails. // 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) thumbnailFilename := fmt.Sprintf("%s/%s_%dpx.jpg", thumbnailPath, canonicalName, size)
if fsutil.Exists(thumbnailFilename) { if util.Exists(thumbnailFilename) {
return NewMediaFile(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) thumbnailFilename := fmt.Sprintf("%s/%s_square_%dpx.jpg", thumbnailPath, canonicalName, size)
if fsutil.Exists(thumbnailFilename) { if util.Exists(thumbnailFilename) {
return NewMediaFile(thumbnailFilename) return NewMediaFile(thumbnailFilename)
} }

View file

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

View file

@ -5,27 +5,27 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/api" "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 // Favicon
router.StaticFile("/favicon.ico", ctx.HttpFaviconsPath()+"/favicon.ico") router.StaticFile("/favicon.ico", conf.HttpFaviconsPath()+"/favicon.ico")
// Static assets like js and css files // Static assets like js and css files
router.Static("/assets", ctx.HttpPublicPath()) router.Static("/assets", conf.HttpPublicPath())
// JSON-REST API Version 1 // JSON-REST API Version 1
v1 := router.Group("/api/v1") v1 := router.Group("/api/v1")
{ {
api.GetPhotos(v1, ctx) api.GetPhotos(v1, conf)
api.GetThumbnail(v1, ctx) api.GetThumbnail(v1, conf)
api.LikePhoto(v1, ctx) api.LikePhoto(v1, conf)
api.DislikePhoto(v1, ctx) api.DislikePhoto(v1, conf)
} }
// Default HTML page (client-side routing implemented via Vue.js) // Default HTML page (client-side routing implemented via Vue.js)
router.NoRoute(func(c *gin.Context) { 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" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/context" "github.com/photoprism/photoprism/internal/config"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// Start the REST API server using the configuration provided // Start the REST API server using the configuration provided
func Start(ctx *context.Context) { func Start(conf *config.Config) {
if ctx.HttpServerMode() != "" { if conf.HttpServerMode() != "" {
gin.SetMode(ctx.HttpServerMode()) gin.SetMode(conf.HttpServerMode())
} else if ctx.Debug() == false { } else if conf.Debug() == false {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
} }
@ -25,19 +25,19 @@ func Start(ctx *context.Context) {
router.Use(gin.Logger(), gin.Recovery()) router.Use(gin.Logger(), gin.Recovery())
// Set template directory // Set template directory
router.LoadHTMLGlob(ctx.HttpTemplatesPath() + "/*") router.LoadHTMLGlob(conf.HttpTemplatesPath() + "/*")
registerRoutes(router, ctx) registerRoutes(router, conf)
server := &http.Server{ server := &http.Server{
Addr: fmt.Sprintf("%s:%d", ctx.HttpServerHost(), ctx.HttpServerPort()), Addr: fmt.Sprintf("%s:%d", conf.HttpServerHost(), conf.HttpServerPort()),
Handler: router, Handler: router,
} }
quit := make(chan os.Signal) 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 See
- https://github.com/gin-gonic/gin/blob/dfe37ea6f1b9127be4cff4822a1308b4349444e0/examples/graceful-shutdown/graceful-shutdown/server.go - 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 <-quit
log.Info("received interrupt signal - shutting down") log.Info("received interrupt signal - shutting down")
ctx.Shutdown() conf.Shutdown()
if err := server.Close(); err != nil { if err := server.Close(); err != nil {
log.Errorf("server close: %s", err) log.Errorf("server close: %s", err)

View file

@ -106,7 +106,7 @@ func Start(path string, port uint, host string, debug bool) {
createServer() 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 See
- https://github.com/gin-gonic/gin/blob/dfe37ea6f1b9127be4cff4822a1308b4349444e0/examples/graceful-shutdown/graceful-shutdown/server.go - 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 ( import (
"bytes" "bytes"

View file

@ -1,4 +1,4 @@
package context package util
import ( import (
"fmt" "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: Additional information can be found in our Developer Guide:
https://github.com/photoprism/photoprism/wiki https://github.com/photoprism/photoprism/wiki
*/ */
package fsutil package util

View file

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

View file

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

View file

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

View file

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

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB