profile.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package profile
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "runtime"
  7. "strings"
  8. "github.com/pkg/errors"
  9. "github.com/spf13/viper"
  10. "github.com/usememos/memos/server/version"
  11. )
  12. // Profile is the configuration to start main server.
  13. type Profile struct {
  14. // Mode can be "prod" or "dev" or "demo"
  15. Mode string `json:"mode"`
  16. // Addr is the binding address for server
  17. Addr string `json:"-"`
  18. // Port is the binding port for server
  19. Port int `json:"-"`
  20. // Data is the data directory
  21. Data string `json:"-"`
  22. // DSN points to where memos stores its own data
  23. DSN string `json:"-"`
  24. // Driver is the database driver
  25. // sqlite, mysql
  26. Driver string `json:"-"`
  27. // Version is the current version of server
  28. Version string `json:"version"`
  29. // Pubic is the flag whether the instance is public for others.
  30. Public bool `json:"public"`
  31. }
  32. func (p *Profile) IsDev() bool {
  33. return p.Mode != "prod"
  34. }
  35. func checkDataDir(dataDir string) (string, error) {
  36. // Convert to absolute path if relative path is supplied.
  37. if !filepath.IsAbs(dataDir) {
  38. relativeDir := filepath.Join(filepath.Dir(os.Args[0]), dataDir)
  39. absDir, err := filepath.Abs(relativeDir)
  40. if err != nil {
  41. return "", err
  42. }
  43. dataDir = absDir
  44. }
  45. // Trim trailing \ or / in case user supplies
  46. dataDir = strings.TrimRight(dataDir, "\\/")
  47. if _, err := os.Stat(dataDir); err != nil {
  48. return "", errors.Wrapf(err, "unable to access data folder %s", dataDir)
  49. }
  50. return dataDir, nil
  51. }
  52. // GetProfile will return a profile for dev or prod.
  53. func GetProfile() (*Profile, error) {
  54. profile := Profile{}
  55. err := viper.Unmarshal(&profile)
  56. if err != nil {
  57. return nil, err
  58. }
  59. if profile.Mode != "demo" && profile.Mode != "dev" && profile.Mode != "prod" {
  60. profile.Mode = "demo"
  61. }
  62. if profile.Mode == "prod" && profile.Data == "" {
  63. if runtime.GOOS == "windows" {
  64. profile.Data = filepath.Join(os.Getenv("ProgramData"), "memos")
  65. if _, err := os.Stat(profile.Data); os.IsNotExist(err) {
  66. if err := os.MkdirAll(profile.Data, 0770); err != nil {
  67. fmt.Printf("Failed to create data directory: %s, err: %+v\n", profile.Data, err)
  68. return nil, err
  69. }
  70. }
  71. } else {
  72. profile.Data = "/var/opt/memos"
  73. }
  74. }
  75. dataDir, err := checkDataDir(profile.Data)
  76. if err != nil {
  77. fmt.Printf("Failed to check dsn: %s, err: %+v\n", dataDir, err)
  78. return nil, err
  79. }
  80. profile.Data = dataDir
  81. if profile.Driver == "sqlite" && profile.DSN == "" {
  82. dbFile := fmt.Sprintf("memos_%s.db", profile.Mode)
  83. profile.DSN = filepath.Join(dataDir, dbFile)
  84. }
  85. profile.Version = version.GetCurrentVersion(profile.Mode)
  86. return &profile, nil
  87. }