add stack test and take new stack

This commit is contained in:
sentriz
2019-06-28 14:26:10 +01:00
parent a4377fc425
commit fb99ecc84e
2 changed files with 55 additions and 20 deletions

View File

@@ -19,6 +19,8 @@ import (
"github.com/sentriz/gonic/scanner/tags" "github.com/sentriz/gonic/scanner/tags"
) )
// IsScanning acts as an atomic boolean semaphore. we don't
// want to have more than one scan going on at a time
var IsScanning int32 var IsScanning int32
var coverFilenames = map[string]struct{}{ var coverFilenames = map[string]struct{}{
@@ -36,6 +38,10 @@ var coverFilenames = map[string]struct{}{
"front.jpeg": {}, "front.jpeg": {},
} }
// decoded converts a string to it's latin equivalent. it
// will be used by the model's *UDec fields, and is only set
// if it differs from the original.
// the fields are used for searching
func decoded(in string) string { func decoded(in string) string {
result := unidecode.Unidecode(in) result := unidecode.Unidecode(in)
if result == in { if result == in {
@@ -51,7 +57,7 @@ type Scanner struct {
seenFolders map[int]struct{} seenFolders map[int]struct{}
seenTracksNew int seenTracksNew int
seenTracksErr int seenTracksErr int
curFolders folderStack curFolders *folderStack
curCover string curCover string
} }
@@ -61,22 +67,10 @@ func New(db *gorm.DB, musicPath string) *Scanner {
musicPath: musicPath, musicPath: musicPath,
seenTracks: make(map[int]struct{}), seenTracks: make(map[int]struct{}),
seenFolders: make(map[int]struct{}), seenFolders: make(map[int]struct{}),
curFolders: make(folderStack, 0), curFolders: &folderStack{},
} }
} }
func (s *Scanner) curFolder() *model.Album {
return s.curFolders.Peek()
}
func (s *Scanner) curFolderID() int {
peek := s.curFolders.Peek()
if peek == nil {
return 0
}
return peek.ID
}
func (s *Scanner) MigrateDB() error { func (s *Scanner) MigrateDB() error {
s.tx = s.db.Begin() s.tx = s.db.Begin()
defer s.tx.Commit() defer s.tx.Commit()
@@ -173,6 +167,7 @@ func (s *Scanner) Start() error {
return nil return nil
} }
// items are passed to the handle*() functions
type item struct { type item struct {
fullPath string fullPath string
relPath string relPath string
@@ -214,9 +209,9 @@ func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error {
} }
func (s *Scanner) callbackPost(fullPath string, info *godirwalk.Dirent) error { func (s *Scanner) callbackPost(fullPath string, info *godirwalk.Dirent) error {
folder := s.curFolders.Pop() folder := s.curFolders.pop()
if folder.ReceivedPaths { if folder.ReceivedPaths {
folder.ParentID = s.curFolderID() folder.ParentID = s.curFolders.peekID()
folder.Cover = s.curCover folder.Cover = s.curCover
s.tx.Save(folder) s.tx.Save(folder)
log.Printf("processed folder `%s`\n", log.Printf("processed folder `%s`\n",
@@ -232,7 +227,7 @@ func (s *Scanner) handleFolder(it *item) error {
// folder's id will come from early return // folder's id will come from early return
// or save at the end // or save at the end
s.seenFolders[folder.ID] = struct{}{} s.seenFolders[folder.ID] = struct{}{}
s.curFolders.Push(folder) s.curFolders.push(folder)
}() }()
err := s.tx. err := s.tx.
Where(model.Album{ Where(model.Album{
@@ -260,7 +255,7 @@ func (s *Scanner) handleTrack(it *item) error {
track := &model.Track{} track := &model.Track{}
err := s.tx. err := s.tx.
Where(model.Track{ Where(model.Track{
AlbumID: s.curFolderID(), AlbumID: s.curFolders.peekID(),
Filename: it.filename, Filename: it.filename,
}). }).
First(track). First(track).
@@ -274,7 +269,7 @@ func (s *Scanner) handleTrack(it *item) error {
track.Filename = it.filename track.Filename = it.filename
track.FilenameUDec = decoded(it.filename) track.FilenameUDec = decoded(it.filename)
track.Size = int(it.stat.Size()) track.Size = int(it.stat.Size())
track.AlbumID = s.curFolderID() track.AlbumID = s.curFolders.peekID()
trTags, err := tags.New(it.fullPath) trTags, err := tags.New(it.fullPath)
if err != nil { if err != nil {
// not returning the error here because we don't // not returning the error here because we don't
@@ -318,7 +313,7 @@ func (s *Scanner) handleTrack(it *item) error {
s.seenTracksNew++ s.seenTracksNew++
// //
// set album if this is the first track in the folder // set album if this is the first track in the folder
folder := s.curFolder() folder := s.curFolders.peek()
if !folder.ReceivedPaths || folder.ReceivedTags { if !folder.ReceivedPaths || folder.ReceivedTags {
// the folder hasn't been modified or already has it's tags // the folder hasn't been modified or already has it's tags
return nil return nil

40
scanner/stack_test.go Normal file
View File

@@ -0,0 +1,40 @@
package scanner
import (
"testing"
"github.com/sentriz/gonic/model"
)
func testAlbum(id int) *model.Album {
return &model.Album{IDBase: model.IDBase{id}}
}
func TestFolderStack(t *testing.T) {
expected := "[6, 5, 4, root]"
//
sta := &folderStack{}
sta.push(testAlbum(3))
sta.push(testAlbum(4))
sta.push(testAlbum(5))
sta.push(testAlbum(6))
actual := sta.string()
if expected != actual {
t.Errorf("first stack: expected string %q, got %q",
expected, actual)
}
//
sta = &folderStack{}
sta.push(testAlbum(3))
sta.push(testAlbum(4))
sta.peek()
sta.push(testAlbum(5))
sta.push(testAlbum(6))
sta.push(testAlbum(7))
sta.pop()
actual = sta.string()
if expected != actual {
t.Errorf("second stack: expected string %q, got %q",
expected, actual)
}
}