mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-13 10:47:19 +03:00
New configuration system
This commit is contained in:
parent
9049d97820
commit
c2b1f9782b
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,4 +9,5 @@ wiki
|
|||||||
TODO.md
|
TODO.md
|
||||||
gosonic.log
|
gosonic.log
|
||||||
var
|
var
|
||||||
Artwork
|
Artwork
|
||||||
|
gosonic.toml
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/deluan/gosonic/api/responses"
|
"github.com/deluan/gosonic/api/responses"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
"github.com/deluan/gosonic/domain"
|
"github.com/deluan/gosonic/domain"
|
||||||
"github.com/deluan/gosonic/engine"
|
"github.com/deluan/gosonic/engine"
|
||||||
"github.com/deluan/gosonic/utils"
|
"github.com/deluan/gosonic/utils"
|
||||||
@ -40,7 +41,7 @@ func (c *BrowsingController) getArtistIndex(ifModifiedSince time.Time) responses
|
|||||||
}
|
}
|
||||||
|
|
||||||
res := responses.Indexes{
|
res := responses.Indexes{
|
||||||
IgnoredArticles: beego.AppConfig.String("ignoredArticles"),
|
IgnoredArticles: conf.GoSonic.IgnoredArticles,
|
||||||
LastModified: fmt.Sprint(utils.ToMillis(lastModified)),
|
LastModified: fmt.Sprint(utils.ToMillis(lastModified)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/deluan/gosonic/api/responses"
|
"github.com/deluan/gosonic/api/responses"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ControllerInterface interface {
|
type ControllerInterface interface {
|
||||||
@ -17,7 +18,7 @@ type ControllerInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Validate(controller BaseAPIController) {
|
func Validate(controller BaseAPIController) {
|
||||||
if beego.AppConfig.String("disableValidation") != "true" {
|
if !conf.GoSonic.DisableValidation {
|
||||||
checkParameters(controller)
|
checkParameters(controller)
|
||||||
authenticate(controller)
|
authenticate(controller)
|
||||||
// TODO Validate version
|
// TODO Validate version
|
||||||
@ -40,7 +41,7 @@ func checkParameters(c BaseAPIController) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func authenticate(c BaseAPIController) {
|
func authenticate(c BaseAPIController) {
|
||||||
password := beego.AppConfig.String("password")
|
password := conf.GoSonic.Password
|
||||||
user := c.GetString("u")
|
user := c.GetString("u")
|
||||||
pass := c.GetString("p")
|
pass := c.GetString("p")
|
||||||
salt := c.GetString("s")
|
salt := c.GetString("s")
|
||||||
@ -61,7 +62,7 @@ func authenticate(c BaseAPIController) {
|
|||||||
valid = (t == token)
|
valid = (t == token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user != beego.AppConfig.String("user") || !valid {
|
if user != conf.GoSonic.User || !valid {
|
||||||
logWarn(c, fmt.Sprintf(`Invalid login for user "%s"`, user))
|
logWarn(c, fmt.Sprintf(`Invalid login for user "%s"`, user))
|
||||||
abortRequest(c, responses.ErrorAuthenticationFail)
|
abortRequest(c, responses.ErrorAuthenticationFail)
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,15 @@
|
|||||||
appname = github.com/deluan/gosonic
|
appname = github.com/deluan/gosonic
|
||||||
serverName = GoSonic
|
serverName = GoSonic
|
||||||
httpPort = 8080
|
|
||||||
runMode = dev
|
runMode = dev
|
||||||
autoRender = false
|
autoRender = false
|
||||||
copyRequestBody = true
|
copyRequestBody = true
|
||||||
enableAdmin = true
|
enableAdmin = false
|
||||||
|
|
||||||
apiVersion = 1.8.0
|
apiVersion = 1.8.0
|
||||||
ignoredArticles="The El La Los Las Le Les Os As O A"
|
|
||||||
indexGroups=A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ) [Unknown]([)
|
|
||||||
|
|
||||||
musicFolder=./iTunes1.xml
|
|
||||||
user=deluan
|
|
||||||
password=wordpass
|
|
||||||
dbPath=./devDb
|
|
||||||
enableDownsampling = true
|
|
||||||
downsampleCommand=ffmpeg -i %s -map 0:0 -b:a %bk -v 0 -f mp3 -
|
|
||||||
plsIgnoreFolders = true
|
|
||||||
plsIgnoredPatterns = ^iCloud;^CDs para;^Skipped;Christian
|
|
||||||
|
|
||||||
[dev]
|
[dev]
|
||||||
disableValidation = true
|
|
||||||
enableAdmin = true
|
enableAdmin = true
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
enableAdmin = false
|
enableAdmin = false
|
||||||
disableValidation = false
|
|
||||||
httpPort = 8081
|
httpPort = 8081
|
||||||
user = deluan
|
|
||||||
password = wordpass
|
|
||||||
dbPath = /tmp/testDb
|
|
||||||
musicFolder = ./tests/itunes-library.xml
|
|
||||||
downsampleCommand = ffmpeg -i %s -b:a %bk mp3 -
|
|
||||||
|
57
conf/configuration.go
Normal file
57
conf/configuration.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package conf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/koding/multiconfig"
|
||||||
|
)
|
||||||
|
|
||||||
|
type goSonic struct {
|
||||||
|
Port int `default:"8080"`
|
||||||
|
MusicFolder string `default:"./iTunes1.xml"`
|
||||||
|
DbPath string `default:"./devDb"`
|
||||||
|
|
||||||
|
IgnoredArticles string `default:"The El La Los Las Le Les Os As O A"`
|
||||||
|
IndexGroups string `default:"A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ) [Unknown]([)"`
|
||||||
|
|
||||||
|
User string `default:"deluan"`
|
||||||
|
Password string `default:"wordpass"`
|
||||||
|
|
||||||
|
DisableDownsampling bool `default:"false"`
|
||||||
|
DisableValidation bool `default:"false"`
|
||||||
|
DownsampleCommand string `default:"ffmpeg -i %s -map 0:0 -b:a %bk -v 0 -f mp3 -"`
|
||||||
|
PlsIgnoreFolders bool `default:"true"`
|
||||||
|
PlsIgnoredPatterns string `default:"^iCloud;^CDs para;^Skipped;Christian"`
|
||||||
|
RunMode string `default:"dev"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var GoSonic *goSonic
|
||||||
|
|
||||||
|
func LoadFromFlags() {
|
||||||
|
l := &multiconfig.FlagLoader{}
|
||||||
|
l.Load(GoSonic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadFromFile(tomlFile string) {
|
||||||
|
l := &multiconfig.TOMLLoader{Path: tomlFile}
|
||||||
|
err := l.Load(GoSonic)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error loading %s: %v\n", tomlFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadFromLocalFile() {
|
||||||
|
if _, err := os.Stat("./gosonic.toml"); err == nil {
|
||||||
|
LoadFromFile("./gosonic.toml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
GoSonic = new(goSonic)
|
||||||
|
var l multiconfig.Loader
|
||||||
|
l = &multiconfig.TagLoader{}
|
||||||
|
l.Load(GoSonic)
|
||||||
|
l = &multiconfig.EnvironmentLoader{}
|
||||||
|
l.Load(GoSonic)
|
||||||
|
}
|
@ -8,14 +8,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO Encapsulate as a io.Reader
|
// TODO Encapsulate as a io.Reader
|
||||||
func Stream(path string, bitRate int, maxBitRate int, w io.Writer) error {
|
func Stream(path string, bitRate int, maxBitRate int, w io.Writer) error {
|
||||||
var f io.Reader
|
var f io.Reader
|
||||||
var err error
|
var err error
|
||||||
ds, _ := beego.AppConfig.Bool("enableDownsampling")
|
enabled := !conf.GoSonic.DisableDownsampling
|
||||||
if ds && maxBitRate > 0 && bitRate > maxBitRate {
|
if enabled && maxBitRate > 0 && bitRate > maxBitRate {
|
||||||
f, err = downsample(path, maxBitRate)
|
f, err = downsample(path, maxBitRate)
|
||||||
} else {
|
} else {
|
||||||
f, err = os.Open(path)
|
f, err = os.Open(path)
|
||||||
@ -44,7 +45,7 @@ func downsample(path string, maxBitRate int) (f io.Reader, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createDownsamplingCommand(path string, maxBitRate int) (string, []string) {
|
func createDownsamplingCommand(path string, maxBitRate int) (string, []string) {
|
||||||
cmd := beego.AppConfig.String("downsampleCommand")
|
cmd := conf.GoSonic.DownsampleCommand
|
||||||
|
|
||||||
split := strings.Split(cmd, " ")
|
split := strings.Split(cmd, " ")
|
||||||
for i, s := range split {
|
for i, s := range split {
|
||||||
|
10
main.go
10
main.go
@ -4,15 +4,23 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
|
_ "github.com/deluan/gosonic/conf"
|
||||||
_ "github.com/deluan/gosonic/init"
|
_ "github.com/deluan/gosonic/init"
|
||||||
_ "github.com/deluan/gosonic/tasks"
|
_ "github.com/deluan/gosonic/tasks"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
conf.LoadFromLocalFile()
|
||||||
|
conf.LoadFromFlags()
|
||||||
|
|
||||||
|
beego.BConfig.RunMode = conf.GoSonic.RunMode
|
||||||
|
beego.BConfig.Listen.HTTPPort = conf.GoSonic.Port
|
||||||
|
|
||||||
fmt.Printf("\nGoSonic v%s (%s mode)\n\n", "0.1", beego.BConfig.RunMode)
|
fmt.Printf("\nGoSonic v%s (%s mode)\n\n", "0.1", beego.BConfig.RunMode)
|
||||||
if beego.BConfig.RunMode == "prod" {
|
if beego.BConfig.RunMode == "prod" {
|
||||||
beego.SetLevel(beego.LevelInformational)
|
beego.SetLevel(beego.LevelInformational)
|
||||||
}
|
}
|
||||||
//beego.BConfig.Log.FileLineNum = false
|
|
||||||
beego.Run()
|
beego.Run()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package persistence
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/deluan/gosonic/conf"
|
||||||
"github.com/siddontang/ledisdb/config"
|
"github.com/siddontang/ledisdb/config"
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
"github.com/siddontang/ledisdb/ledis"
|
||||||
)
|
)
|
||||||
@ -17,7 +17,7 @@ var (
|
|||||||
func Db() *ledis.DB {
|
func Db() *ledis.DB {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
config := config.NewConfigDefault()
|
config := config.NewConfigDefault()
|
||||||
config.DataDir = beego.AppConfig.String("dbPath")
|
config.DataDir = conf.GoSonic.DbPath
|
||||||
l, _ := ledis.Open(config)
|
l, _ := ledis.Open(config)
|
||||||
instance, err := l.Select(0)
|
instance, err := l.Select(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package persistence
|
package persistence
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/astaxie/beego"
|
"github.com/deluan/gosonic/conf"
|
||||||
"github.com/deluan/gosonic/domain"
|
"github.com/deluan/gosonic/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ func NewMediaFolderRepository() domain.MediaFolderRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (*mediaFolderRepository) GetAll() (domain.MediaFolders, error) {
|
func (*mediaFolderRepository) GetAll() (domain.MediaFolders, error) {
|
||||||
mediaFolder := domain.MediaFolder{Id: "0", Name: "iTunes Library", Path: beego.AppConfig.String("musicFolder")}
|
mediaFolder := domain.MediaFolder{Id: "0", Name: "iTunes Library", Path: conf.GoSonic.MusicFolder}
|
||||||
result := make(domain.MediaFolders, 1)
|
result := make(domain.MediaFolders, 1)
|
||||||
result[0] = mediaFolder
|
result[0] = mediaFolder
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
"github.com/deluan/gosonic/domain"
|
"github.com/deluan/gosonic/domain"
|
||||||
"github.com/deluan/gosonic/engine"
|
"github.com/deluan/gosonic/engine"
|
||||||
"github.com/deluan/gosonic/utils"
|
"github.com/deluan/gosonic/utils"
|
||||||
@ -49,7 +50,7 @@ func CheckForUpdates(force bool) {
|
|||||||
|
|
||||||
func startImport() {
|
func startImport() {
|
||||||
go func() {
|
go func() {
|
||||||
itunesLibrary = beego.AppConfig.String("musicFolder")
|
itunesLibrary = conf.GoSonic.MusicFolder
|
||||||
|
|
||||||
info, err := os.Stat(itunesLibrary)
|
info, err := os.Stat(itunesLibrary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -64,7 +65,7 @@ func startImport() {
|
|||||||
lastCheck = time.Now()
|
lastCheck = time.Now()
|
||||||
|
|
||||||
// TODO Move all to DI
|
// TODO Move all to DI
|
||||||
i := &Importer{mediaFolder: beego.AppConfig.String("musicFolder")}
|
i := &Importer{mediaFolder: itunesLibrary}
|
||||||
utils.ResolveDependencies(&i.mfRepo, &i.albumRepo, &i.artistRepo, &i.idxRepo, &i.plsRepo,
|
utils.ResolveDependencies(&i.mfRepo, &i.albumRepo, &i.artistRepo, &i.idxRepo, &i.plsRepo,
|
||||||
&i.propertyRepo, &i.search, &i.scanner)
|
&i.propertyRepo, &i.search, &i.scanner)
|
||||||
i.Run()
|
i.Run()
|
||||||
@ -263,7 +264,7 @@ func (i *Importer) importArtists() domain.Artists {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Importer) importArtistIndex() {
|
func (i *Importer) importArtistIndex() {
|
||||||
indexGroups := utils.ParseIndexGroups(beego.AppConfig.String("indexGroups"))
|
indexGroups := utils.ParseIndexGroups(conf.GoSonic.IndexGroups)
|
||||||
artistIndex := make(map[string]tempIndex)
|
artistIndex := make(map[string]tempIndex)
|
||||||
|
|
||||||
for _, ar := range i.scanner.Artists() {
|
for _, ar := range i.scanner.Artists() {
|
||||||
@ -280,7 +281,7 @@ func (i *Importer) importPlaylists() domain.Playlists {
|
|||||||
j := 0
|
j := 0
|
||||||
for _, pl := range i.scanner.Playlists() {
|
for _, pl := range i.scanner.Playlists() {
|
||||||
pl.Public = true
|
pl.Public = true
|
||||||
pl.Owner = beego.AppConfig.String("user")
|
pl.Owner = conf.GoSonic.User
|
||||||
pl.Comment = "Original: " + pl.FullPath
|
pl.Comment = "Original: " + pl.FullPath
|
||||||
pls[j] = *pl
|
pls[j] = *pl
|
||||||
j++
|
j++
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
"github.com/deluan/gosonic/domain"
|
"github.com/deluan/gosonic/domain"
|
||||||
"github.com/deluan/itl"
|
"github.com/deluan/itl"
|
||||||
"github.com/dhowden/tag"
|
"github.com/dhowden/tag"
|
||||||
@ -102,8 +103,8 @@ func (s *ItunesScanner) ScanLibrary(lastModifiedSince time.Time, path string) (i
|
|||||||
beego.Debug("Saved", len(s.newSums), "checksums")
|
beego.Debug("Saved", len(s.newSums), "checksums")
|
||||||
}
|
}
|
||||||
|
|
||||||
ignFolders, _ := beego.AppConfig.Bool("plsIgnoreFolders")
|
ignFolders := conf.GoSonic.PlsIgnoreFolders
|
||||||
ignPatterns := beego.AppConfig.Strings("plsIgnoredPatterns")
|
ignPatterns := strings.Split(conf.GoSonic.PlsIgnoredPatterns, ";")
|
||||||
for _, p := range l.Playlists {
|
for _, p := range l.Playlists {
|
||||||
rel := plsRelation{pID: p.PlaylistPersistentID, parentPID: p.ParentPersistentID, name: unescape(p.Name)}
|
rel := plsRelation{pID: p.PlaylistPersistentID, parentPID: p.ParentPersistentID, name: unescape(p.Name)}
|
||||||
s.pplaylists[p.PlaylistPersistentID] = rel
|
s.pplaylists[p.PlaylistPersistentID] = rel
|
||||||
|
6
tests/gosonic-test.toml
Normal file
6
tests/gosonic-test.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
DisableValidation = false
|
||||||
|
User = "deluan"
|
||||||
|
Password = "wordpass"
|
||||||
|
DbPath = "/tmp/testDb"
|
||||||
|
MusicFolder = "./tests/itunes-library.xml"
|
||||||
|
DownsampleCommand = "ffmpeg -i %s -b:a %bk mp3 -"
|
@ -7,10 +7,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
"github.com/deluan/gosonic/conf"
|
||||||
"github.com/deluan/gosonic/utils"
|
"github.com/deluan/gosonic/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init(t *testing.T, skipOnShort bool) {
|
func Init(t *testing.T, skipOnShort bool) {
|
||||||
|
conf.LoadFromFile("../tests/gosonic-test.toml")
|
||||||
if skipOnShort && testing.Short() {
|
if skipOnShort && testing.Short() {
|
||||||
t.Skip("skipping test in short mode.")
|
t.Skip("skipping test in short mode.")
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/deluan/gosonic/conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NoArticle(name string) string {
|
func NoArticle(name string) string {
|
||||||
articles := strings.Split(beego.AppConfig.String("ignoredArticles"), " ")
|
articles := strings.Split(conf.GoSonic.IgnoredArticles, " ")
|
||||||
for _, a := range articles {
|
for _, a := range articles {
|
||||||
n := strings.TrimPrefix(name, a+" ")
|
n := strings.TrimPrefix(name, a+" ")
|
||||||
if n != name {
|
if n != name {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user