profile.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. // Version is the current version of server
  25. Version string `json:"version"`
  26. }
  27. func (p *Profile) IsDev() bool {
  28. return p.Mode != "prod"
  29. }
  30. func checkDSN(dataDir string) (string, error) {
  31. // Convert to absolute path if relative path is supplied.
  32. if !filepath.IsAbs(dataDir) {
  33. relativeDir := filepath.Join(filepath.Dir(os.Args[0]), dataDir)
  34. absDir, err := filepath.Abs(relativeDir)
  35. if err != nil {
  36. return "", err
  37. }
  38. dataDir = absDir
  39. }
  40. // Trim trailing \ or / in case user supplies
  41. dataDir = strings.TrimRight(dataDir, "\\/")
  42. if _, err := os.Stat(dataDir); err != nil {
  43. return "", errors.Wrapf(err, "unable to access data folder %s", dataDir)
  44. }
  45. return dataDir, nil
  46. }
  47. // GetProfile will return a profile for dev or prod.
  48. func GetProfile() (*Profile, error) {
  49. profile := Profile{}
  50. err := viper.Unmarshal(&profile)
  51. if err != nil {
  52. return nil, err
  53. }
  54. if profile.Mode != "demo" && profile.Mode != "dev" && profile.Mode != "prod" {
  55. profile.Mode = "demo"
  56. }
  57. if profile.Mode == "prod" && profile.Data == "" {
  58. if runtime.GOOS == "windows" {
  59. profile.Data = filepath.Join(os.Getenv("ProgramData"), "memos")
  60. if _, err := os.Stat(profile.Data); os.IsNotExist(err) {
  61. if err := os.MkdirAll(profile.Data, 0770); err != nil {
  62. fmt.Printf("Failed to create data directory: %s, err: %+v\n", profile.Data, err)
  63. return nil, err
  64. }
  65. }
  66. } else {
  67. profile.Data = "/var/opt/memos"
  68. }
  69. }
  70. dataDir, err := checkDSN(profile.Data)
  71. if err != nil {
  72. fmt.Printf("Failed to check dsn: %s, err: %+v\n", dataDir, err)
  73. return nil, err
  74. }
  75. profile.Data = dataDir
  76. dbFile := fmt.Sprintf("memos_%s.db", profile.Mode)
  77. profile.DSN = filepath.Join(dataDir, dbFile)
  78. profile.Version = version.GetCurrentVersion(profile.Mode)
  79. return &profile, nil
  80. }