mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-18 21:07:44 +03:00
More experimenting with tiedot
This commit is contained in:
parent
4f9054b738
commit
ecc0df9e7c
13
README.md
13
README.md
@ -40,9 +40,16 @@ $ gopm get -v -g
|
|||||||
|
|
||||||
From here it's a normal [BeeGo](http://beego.me) development cycle. Some useful commands:
|
From here it's a normal [BeeGo](http://beego.me) development cycle. Some useful commands:
|
||||||
|
|
||||||
* Start local server with `bee run`
|
```bash
|
||||||
* Start test runner on the browser with `NOLOG=1 goconvey --port 9090`
|
# Start local server (with hot reload)
|
||||||
* Test from command line with `go test ./... -v`
|
$ bee run
|
||||||
|
|
||||||
|
# Start test runner on the browser
|
||||||
|
$ NOLOG=1 goconvey --port 9090
|
||||||
|
|
||||||
|
# Runa all tests
|
||||||
|
$ go test ./... -v
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Useful Links
|
### Useful Links
|
||||||
|
@ -5,7 +5,10 @@ autoRender = false
|
|||||||
copyRequestBody = true
|
copyRequestBody = true
|
||||||
|
|
||||||
apiVersion = 1.0.0
|
apiVersion = 1.0.0
|
||||||
musicFolder=./iTunes.xml
|
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)
|
||||||
|
|
||||||
|
musicFolder=./iTunesFull.xml
|
||||||
user=deluan
|
user=deluan
|
||||||
password=wordpass
|
password=wordpass
|
||||||
dbPath = ./devDb
|
dbPath = ./devDb
|
||||||
@ -21,4 +24,4 @@ httpPort = 8081
|
|||||||
enableAdmin = false
|
enableAdmin = false
|
||||||
user=deluan
|
user=deluan
|
||||||
password=wordpass
|
password=wordpass
|
||||||
dbPath = ./tmp/testDb
|
dbPath = /tmp/testDb
|
@ -1,6 +1,22 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"github.com/astaxie/beego"
|
||||||
|
)
|
||||||
|
|
||||||
type Artist struct {
|
type Artist struct {
|
||||||
Id string
|
Id string
|
||||||
Name string
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NoArticle(name string) string {
|
||||||
|
articles := strings.Split(beego.AppConfig.String("ignoredArticles"), " ")
|
||||||
|
for _, a := range articles {
|
||||||
|
n := strings.TrimPrefix(name, a + " ")
|
||||||
|
if (n != name) {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name
|
||||||
}
|
}
|
@ -1,13 +1,27 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type MediaFile struct {
|
type MediaFile struct {
|
||||||
Id string
|
Id string
|
||||||
Path string
|
Path string
|
||||||
Album string
|
Title string
|
||||||
Artist string
|
Album string
|
||||||
Title string
|
Artist string
|
||||||
CreatedAt time.Time
|
AlbumArtist string
|
||||||
UpdatedAt time.Time
|
Compilation bool
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m*MediaFile) RealArtist() string {
|
||||||
|
if (m.Compilation) {
|
||||||
|
return "Various Artists"
|
||||||
|
}
|
||||||
|
if (m.AlbumArtist != "") {
|
||||||
|
return m.AlbumArtist
|
||||||
|
}
|
||||||
|
return m.Artist
|
||||||
}
|
}
|
@ -56,7 +56,7 @@ func (r *BaseRepository) saveOrUpdate(rec interface{}) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docId, err := r.queryFirstKey(`{"in": ["Id"], "eq": "%s"}`, m["Id"])
|
docId, err := r.queryFirstKey(`{"in": ["Id"], "eq": "%s", "limit": 1}`, m["Id"])
|
||||||
if docId == 0 {
|
if docId == 0 {
|
||||||
_, err = r.col.Insert(m)
|
_, err = r.col.Insert(m)
|
||||||
return err
|
return err
|
||||||
|
@ -11,20 +11,38 @@ var (
|
|||||||
once sync.Once
|
once sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
func createCollection(name string) *db.Col {
|
func createCollection(name string, ix ...interface{}) *db.Col {
|
||||||
|
log := false
|
||||||
|
if dbInstance().Use(name) == nil {
|
||||||
|
if err := dbInstance().Create(name); err != nil {
|
||||||
|
beego.Error(err)
|
||||||
|
}
|
||||||
|
log = true
|
||||||
|
}
|
||||||
|
|
||||||
col := dbInstance().Use(name)
|
col := dbInstance().Use(name)
|
||||||
if col != nil {
|
|
||||||
return col
|
createIndex(col, []string{"Id"}, log)
|
||||||
}
|
for _, i := range ix {
|
||||||
if err := dbInstance().Create(name); err != nil {
|
switch i := i.(type) {
|
||||||
beego.Error(err)
|
case string:
|
||||||
}
|
createIndex(col, []string{i}, log)
|
||||||
if err := col.Index([]string{"Id"}); err != nil {
|
case []string:
|
||||||
beego.Error(name, err)
|
createIndex(col, i, log)
|
||||||
|
default:
|
||||||
|
beego.Error("Trying to create an Index with an invalid type: ", i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return col
|
return col
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createIndex(col *db.Col, path []string, log bool) (err error) {
|
||||||
|
if err := col.Index(path); err != nil && log {
|
||||||
|
beego.Error(path, err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func dbInstance() *db.DB {
|
func dbInstance() *db.DB {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
instance, err := db.OpenDB(beego.AppConfig.String("dbPath"))
|
instance, err := db.OpenDB(beego.AppConfig.String("dbPath"))
|
||||||
|
54
repositories/init_database_test.go
Normal file
54
repositories/init_database_test.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
_ "github.com/deluan/gosonic/tests"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
testCollectionName = "TestCollection"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateCollection(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
dbInstance().Drop(testCollectionName)
|
||||||
|
|
||||||
|
Convey("Given an empty DB", t, func() {
|
||||||
|
|
||||||
|
Convey("When creating a new collection", func() {
|
||||||
|
newCol := createCollection(testCollectionName)
|
||||||
|
|
||||||
|
Convey("Then it should create the collection", func() {
|
||||||
|
So(dbInstance().Use(testCollectionName), ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
Convey("And it should create a default index on Id", func() {
|
||||||
|
allIndexes := newCol.AllIndexes()
|
||||||
|
So(len(allIndexes), ShouldEqual, 1)
|
||||||
|
So(len(allIndexes[0]), ShouldEqual, 1)
|
||||||
|
So(allIndexes[0], ShouldContain, "Id")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("When creating a new collection with a 'Name' index", func() {
|
||||||
|
newCol := createCollection(testCollectionName, "Name")
|
||||||
|
|
||||||
|
Convey("Then it should create a default index [Id] and an index on 'Name'", func() {
|
||||||
|
listOfIndexes := newCol.AllIndexes()
|
||||||
|
|
||||||
|
So(len(listOfIndexes), ShouldEqual, 2)
|
||||||
|
|
||||||
|
var allPaths = make(map[string]bool)
|
||||||
|
for _, i := range listOfIndexes {
|
||||||
|
allPaths[i[0]] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
So(allPaths, ShouldContainKey, "Id")
|
||||||
|
So(allPaths, ShouldContainKey, "Name")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
@ -21,6 +21,8 @@ func (s *ItunesScanner) LoadFolder(path string) []Track {
|
|||||||
mediaFiles[i].Album = t.Album
|
mediaFiles[i].Album = t.Album
|
||||||
mediaFiles[i].Title = t.Name
|
mediaFiles[i].Title = t.Name
|
||||||
mediaFiles[i].Artist = t.Artist
|
mediaFiles[i].Artist = t.Artist
|
||||||
|
mediaFiles[i].AlbumArtist = t.AlbumArtist
|
||||||
|
mediaFiles[i].Compilation = t.Compilation
|
||||||
path, _ = url.QueryUnescape(t.Location)
|
path, _ = url.QueryUnescape(t.Location)
|
||||||
mediaFiles[i].Path = strings.TrimPrefix(path, "file://")
|
mediaFiles[i].Path = strings.TrimPrefix(path, "file://")
|
||||||
mediaFiles[i].CreatedAt = t.DateAdded
|
mediaFiles[i].CreatedAt = t.DateAdded
|
||||||
|
@ -4,6 +4,9 @@ import (
|
|||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/deluan/gosonic/repositories"
|
"github.com/deluan/gosonic/repositories"
|
||||||
"github.com/deluan/gosonic/models"
|
"github.com/deluan/gosonic/models"
|
||||||
|
"strings"
|
||||||
|
"fmt"
|
||||||
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Scanner interface {
|
type Scanner interface {
|
||||||
@ -23,12 +26,15 @@ func doImport(mediaFolder string, scanner Scanner) {
|
|||||||
|
|
||||||
func updateDatastore(files []Track) {
|
func updateDatastore(files []Track) {
|
||||||
mfRepo := repositories.NewMediaFileRepository()
|
mfRepo := repositories.NewMediaFileRepository()
|
||||||
|
var artistIndex = make(map[string]map[string]string)
|
||||||
for _, t := range files {
|
for _, t := range files {
|
||||||
m := &models.MediaFile{
|
m := &models.MediaFile{
|
||||||
Id: t.Id,
|
Id: t.Id,
|
||||||
Album: t.Album,
|
Album: t.Album,
|
||||||
Artist: t.Artist,
|
Artist: t.Artist,
|
||||||
|
AlbumArtist: t.AlbumArtist,
|
||||||
Title: t.Title,
|
Title: t.Title,
|
||||||
|
Compilation: t.Compilation,
|
||||||
Path: t.Path,
|
Path: t.Path,
|
||||||
CreatedAt: t.CreatedAt,
|
CreatedAt: t.CreatedAt,
|
||||||
UpdatedAt: t.UpdatedAt,
|
UpdatedAt: t.UpdatedAt,
|
||||||
@ -37,6 +43,24 @@ func updateDatastore(files []Track) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
beego.Error(err)
|
beego.Error(err)
|
||||||
}
|
}
|
||||||
|
collectIndex(m, artistIndex)
|
||||||
}
|
}
|
||||||
mfRepo.Dump()
|
//mfRepo.Dump()
|
||||||
|
j,_ := json.MarshalIndent(artistIndex, "", " ")
|
||||||
|
fmt.Println(string(j))
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectIndex(m *models.MediaFile, artistIndex map[string]map[string]string) {
|
||||||
|
name := m.RealArtist()
|
||||||
|
indexName := strings.ToLower(models.NoArticle(name))
|
||||||
|
if indexName == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
initial := strings.ToUpper(indexName[0:1])
|
||||||
|
artists := artistIndex[initial]
|
||||||
|
if artists == nil {
|
||||||
|
artists = make(map[string]string)
|
||||||
|
artistIndex[initial] = artists
|
||||||
|
}
|
||||||
|
artists[indexName] = name
|
||||||
}
|
}
|
@ -5,11 +5,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Track struct {
|
type Track struct {
|
||||||
Id string
|
Id string
|
||||||
Path string
|
Path string
|
||||||
Album string
|
Title string
|
||||||
Artist string
|
Album string
|
||||||
Title string
|
Artist string
|
||||||
CreatedAt time.Time
|
AlbumArtist string
|
||||||
UpdatedAt time.Time
|
Compilation bool
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package api_test
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package api_test
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/deluan/gosonic/routers"
|
_ "github.com/deluan/gosonic/routers"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package api_test
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package api_test
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user