refactor
This commit is contained in:
@@ -33,7 +33,7 @@ func New(db *gorm.DB, musicPath string) *Scanner {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scanner) curFolder() *model.Folder {
|
||||
func (s *Scanner) curFolder() *model.Album {
|
||||
return s.curFolders.Peek()
|
||||
}
|
||||
|
||||
@@ -45,6 +45,26 @@ func (s *Scanner) curFolderID() int {
|
||||
return peek.ID
|
||||
}
|
||||
|
||||
func (s *Scanner) MigrateDB() error {
|
||||
defer logElapsed(time.Now(), "migrating database")
|
||||
s.tx = s.db.Begin()
|
||||
defer s.tx.Commit()
|
||||
s.tx.AutoMigrate(
|
||||
model.Artist{},
|
||||
model.Track{},
|
||||
model.User{},
|
||||
model.Setting{},
|
||||
model.Play{},
|
||||
model.Album{},
|
||||
)
|
||||
s.tx.FirstOrCreate(&model.User{}, model.User{
|
||||
Name: "admin",
|
||||
Password: "admin",
|
||||
IsAdmin: true,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scanner) Start() error {
|
||||
if atomic.LoadInt32(&IsScanning) == 1 {
|
||||
return errors.New("already scanning")
|
||||
@@ -82,38 +102,22 @@ func (s *Scanner) startScan() error {
|
||||
|
||||
func (s *Scanner) startClean() error {
|
||||
defer logElapsed(time.Now(), "cleaning database")
|
||||
var tracks []model.Track
|
||||
s.tx.
|
||||
var tracks []*model.Track
|
||||
err := s.tx.
|
||||
Select("id").
|
||||
Find(&tracks)
|
||||
Find(&tracks).
|
||||
Error
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "scanning tracks")
|
||||
}
|
||||
var deleted int
|
||||
for _, track := range tracks {
|
||||
_, ok := s.seenTracks[track.ID]
|
||||
if !ok {
|
||||
s.tx.Delete(&track)
|
||||
s.tx.Delete(track)
|
||||
deleted++
|
||||
}
|
||||
}
|
||||
log.Printf("removed %d tracks\n", deleted)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scanner) MigrateDB() error {
|
||||
defer logElapsed(time.Now(), "migrating database")
|
||||
s.tx = s.db.Begin()
|
||||
defer s.tx.Commit()
|
||||
s.tx.AutoMigrate(
|
||||
model.Artist{},
|
||||
model.Track{},
|
||||
model.User{},
|
||||
model.Setting{},
|
||||
model.Play{},
|
||||
model.Folder{},
|
||||
)
|
||||
s.tx.FirstOrCreate(&model.User{}, model.User{
|
||||
Name: "admin",
|
||||
Password: "admin",
|
||||
IsAdmin: true,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"github.com/sentriz/gonic/model"
|
||||
)
|
||||
|
||||
type folderStack []*model.Folder
|
||||
type folderStack []*model.Album
|
||||
|
||||
func (s *folderStack) Push(v *model.Folder) {
|
||||
func (s *folderStack) Push(v *model.Album) {
|
||||
*s = append(*s, v)
|
||||
}
|
||||
|
||||
func (s *folderStack) Pop() *model.Folder {
|
||||
func (s *folderStack) Pop() *model.Album {
|
||||
l := len(*s)
|
||||
if l == 0 {
|
||||
return nil
|
||||
@@ -23,7 +23,7 @@ func (s *folderStack) Pop() *model.Folder {
|
||||
return r
|
||||
}
|
||||
|
||||
func (s *folderStack) Peek() *model.Folder {
|
||||
func (s *folderStack) Peek() *model.Album {
|
||||
l := len(*s)
|
||||
if l == 0 {
|
||||
return nil
|
||||
@@ -34,7 +34,7 @@ func (s *folderStack) Peek() *model.Folder {
|
||||
func (s *folderStack) String() string {
|
||||
paths := make([]string, len(*s))
|
||||
for i, folder := range *s {
|
||||
paths[i] = folder.Path
|
||||
paths[i] = folder.LeftPath
|
||||
}
|
||||
return fmt.Sprintf("[%s]", strings.Join(paths, " "))
|
||||
}
|
||||
@@ -7,27 +7,19 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var mimeTypes = map[string]string{
|
||||
"mp3": "audio/mpeg",
|
||||
"flac": "audio/x-flac",
|
||||
"aac": "audio/x-aac",
|
||||
"m4a": "audio/m4a",
|
||||
"ogg": "audio/ogg",
|
||||
}
|
||||
|
||||
var coverFilenames = map[string]struct{}{
|
||||
"cover.png": struct{}{},
|
||||
"cover.jpg": struct{}{},
|
||||
"cover.jpeg": struct{}{},
|
||||
"folder.png": struct{}{},
|
||||
"folder.jpg": struct{}{},
|
||||
"folder.jpeg": struct{}{},
|
||||
"album.png": struct{}{},
|
||||
"album.jpg": struct{}{},
|
||||
"album.jpeg": struct{}{},
|
||||
"front.png": struct{}{},
|
||||
"front.jpg": struct{}{},
|
||||
"front.jpeg": struct{}{},
|
||||
"cover.png": {},
|
||||
"cover.jpg": {},
|
||||
"cover.jpeg": {},
|
||||
"folder.png": {},
|
||||
"folder.jpg": {},
|
||||
"folder.jpeg": {},
|
||||
"album.png": {},
|
||||
"album.jpg": {},
|
||||
"album.jpeg": {},
|
||||
"front.png": {},
|
||||
"front.jpg": {},
|
||||
"front.jpeg": {},
|
||||
}
|
||||
|
||||
func readTags(path string) (tag.Metadata, error) {
|
||||
|
||||
@@ -10,20 +10,16 @@ import (
|
||||
"github.com/karrick/godirwalk"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/sentriz/gonic/mime"
|
||||
"github.com/sentriz/gonic/model"
|
||||
)
|
||||
|
||||
type item struct {
|
||||
//
|
||||
// common
|
||||
fullPath string
|
||||
relPath string
|
||||
filename string
|
||||
stat os.FileInfo
|
||||
//
|
||||
// track only
|
||||
ext string
|
||||
mime string
|
||||
fullPath string
|
||||
relPath string
|
||||
directory string
|
||||
filename string
|
||||
stat os.FileInfo
|
||||
}
|
||||
|
||||
func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error {
|
||||
@@ -35,12 +31,13 @@ func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting relative path")
|
||||
}
|
||||
_, filename := path.Split(relPath)
|
||||
directory, filename := path.Split(relPath)
|
||||
it := &item{
|
||||
fullPath: fullPath,
|
||||
relPath: relPath,
|
||||
filename: filename,
|
||||
stat: stat,
|
||||
fullPath: fullPath,
|
||||
relPath: relPath,
|
||||
directory: directory,
|
||||
filename: filename,
|
||||
stat: stat,
|
||||
}
|
||||
if info.IsDir() {
|
||||
return s.handleFolder(it)
|
||||
@@ -50,9 +47,7 @@ func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error {
|
||||
return nil
|
||||
}
|
||||
ext := path.Ext(filename)[1:]
|
||||
if mime, ok := mimeTypes[ext]; ok {
|
||||
it.ext = ext
|
||||
it.mime = mime
|
||||
if _, ok := mime.Types[ext]; ok {
|
||||
return s.handleTrack(it)
|
||||
}
|
||||
return nil
|
||||
@@ -71,9 +66,12 @@ func (s *Scanner) callbackPost(fullPath string, info *godirwalk.Dirent) error {
|
||||
}
|
||||
|
||||
func (s *Scanner) handleFolder(it *item) error {
|
||||
var folder model.Folder
|
||||
var folder model.Album
|
||||
err := s.tx.
|
||||
Where("path = ?", it.relPath).
|
||||
Where(model.Album{
|
||||
LeftPath: it.directory,
|
||||
RightPath: it.filename,
|
||||
}).
|
||||
First(&folder).
|
||||
Error
|
||||
if !gorm.IsRecordNotFoundError(err) &&
|
||||
@@ -82,7 +80,8 @@ func (s *Scanner) handleFolder(it *item) error {
|
||||
s.curFolders.Push(&folder)
|
||||
return nil
|
||||
}
|
||||
folder.Path = it.relPath
|
||||
folder.LeftPath = it.directory
|
||||
folder.RightPath = it.filename
|
||||
s.tx.Save(&folder)
|
||||
folder.IsNew = true
|
||||
s.curFolders.Push(&folder)
|
||||
@@ -95,7 +94,7 @@ func (s *Scanner) handleTrack(it *item) error {
|
||||
var track model.Track
|
||||
err := s.tx.
|
||||
Where(model.Track{
|
||||
FolderID: s.curFolderID(),
|
||||
AlbumID: s.curFolderID(),
|
||||
Filename: it.filename,
|
||||
}).
|
||||
First(&track).
|
||||
@@ -107,9 +106,8 @@ func (s *Scanner) handleTrack(it *item) error {
|
||||
return nil
|
||||
}
|
||||
track.Filename = it.filename
|
||||
track.ContentType = it.mime
|
||||
track.Size = int(it.stat.Size())
|
||||
track.FolderID = s.curFolderID()
|
||||
track.AlbumID = s.curFolderID()
|
||||
track.Duration = -1
|
||||
track.Bitrate = -1
|
||||
tags, err := readTags(it.fullPath)
|
||||
@@ -128,7 +126,8 @@ func (s *Scanner) handleTrack(it *item) error {
|
||||
//
|
||||
// set album artist basics
|
||||
var artist model.Artist
|
||||
err = s.tx.Where("name = ?", tags.AlbumArtist()).
|
||||
err = s.tx.
|
||||
Where("name = ?", tags.AlbumArtist()).
|
||||
First(&artist).
|
||||
Error
|
||||
if gorm.IsRecordNotFoundError(err) {
|
||||
@@ -143,8 +142,8 @@ func (s *Scanner) handleTrack(it *item) error {
|
||||
if !s.curFolder().IsNew {
|
||||
return nil
|
||||
}
|
||||
s.curFolder().AlbumTitle = tags.Album()
|
||||
s.curFolder().AlbumYear = tags.Year()
|
||||
s.curFolder().AlbumArtistID = artist.ID
|
||||
s.curFolder().TagTitle = tags.Album()
|
||||
s.curFolder().TagYear = tags.Year()
|
||||
s.curFolder().TagArtistID = artist.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user