show last element in stack string
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
"github.com/sentriz/gonic/mime"
|
"github.com/sentriz/gonic/mime"
|
||||||
"github.com/sentriz/gonic/model"
|
"github.com/sentriz/gonic/model"
|
||||||
|
"github.com/sentriz/gonic/scanner/stack"
|
||||||
"github.com/sentriz/gonic/scanner/tags"
|
"github.com/sentriz/gonic/scanner/tags"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ type Scanner struct {
|
|||||||
seenFolders map[int]struct{}
|
seenFolders map[int]struct{}
|
||||||
seenTracksNew int
|
seenTracksNew int
|
||||||
seenTracksErr int
|
seenTracksErr int
|
||||||
curFolders *folderStack
|
curFolders *stack.Stack
|
||||||
curCover string
|
curCover string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ 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: &folderStack{},
|
curFolders: &stack.Stack{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,9 +210,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.curFolders.peekID()
|
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",
|
||||||
@@ -227,7 +228,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{
|
||||||
@@ -255,7 +256,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.curFolders.peekID(),
|
AlbumID: s.curFolders.PeekID(),
|
||||||
Filename: it.filename,
|
Filename: it.filename,
|
||||||
}).
|
}).
|
||||||
First(track).
|
First(track).
|
||||||
@@ -269,7 +270,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.curFolders.peekID()
|
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
|
||||||
@@ -313,7 +314,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.curFolders.peek()
|
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
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package scanner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/sentriz/gonic/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type folderItem struct {
|
|
||||||
value *model.Album
|
|
||||||
next *folderItem
|
|
||||||
}
|
|
||||||
|
|
||||||
type folderStack struct {
|
|
||||||
top *folderItem
|
|
||||||
len uint
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *folderStack) push(v *model.Album) {
|
|
||||||
s.top = &folderItem{
|
|
||||||
value: v,
|
|
||||||
next: s.top,
|
|
||||||
}
|
|
||||||
s.len++
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *folderStack) pop() *model.Album {
|
|
||||||
if s.len == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
v := s.top.value
|
|
||||||
s.top = s.top.next
|
|
||||||
s.len--
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *folderStack) peek() *model.Album {
|
|
||||||
if s.len == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return s.top.value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *folderStack) peekID() int {
|
|
||||||
if s.len == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return s.top.value.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *folderStack) string() string {
|
|
||||||
var str strings.Builder
|
|
||||||
str.WriteString("[")
|
|
||||||
for i := s.top; i.next != nil; i = i.next {
|
|
||||||
str.WriteString(fmt.Sprintf("%d, ", i.value.ID))
|
|
||||||
}
|
|
||||||
str.WriteString("root]")
|
|
||||||
return str.String()
|
|
||||||
}
|
|
||||||
61
scanner/stack/stack.go
Normal file
61
scanner/stack/stack.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package stack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/sentriz/gonic/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type item struct {
|
||||||
|
value *model.Album
|
||||||
|
next *item
|
||||||
|
}
|
||||||
|
|
||||||
|
type Stack struct {
|
||||||
|
top *item
|
||||||
|
len uint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack) Push(v *model.Album) {
|
||||||
|
s.top = &item{
|
||||||
|
value: v,
|
||||||
|
next: s.top,
|
||||||
|
}
|
||||||
|
s.len++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack) Pop() *model.Album {
|
||||||
|
if s.len == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
v := s.top.value
|
||||||
|
s.top = s.top.next
|
||||||
|
s.len--
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack) Peek() *model.Album {
|
||||||
|
if s.len == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return s.top.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack) PeekID() int {
|
||||||
|
if s.len == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return s.top.value.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack) String() string {
|
||||||
|
var str strings.Builder
|
||||||
|
str.WriteString("[")
|
||||||
|
for i, f := uint(0), s.top; i < s.len; i++ {
|
||||||
|
str.WriteString(fmt.Sprintf("%d, ", f.value.ID))
|
||||||
|
f = f.next
|
||||||
|
}
|
||||||
|
str.WriteString("]")
|
||||||
|
return str.String()
|
||||||
|
}
|
||||||
40
scanner/stack/stack_test.go
Normal file
40
scanner/stack/stack_test.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package stack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/sentriz/gonic/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func egAlbum(id int) *model.Album {
|
||||||
|
return &model.Album{IDBase: model.IDBase{id}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFolderStack(t *testing.T) {
|
||||||
|
sta := &Stack{}
|
||||||
|
sta.Push(egAlbum(3))
|
||||||
|
sta.Push(egAlbum(4))
|
||||||
|
sta.Push(egAlbum(5))
|
||||||
|
sta.Push(egAlbum(6))
|
||||||
|
expected := "[6, 5, 4, 3, ]"
|
||||||
|
actual := sta.String()
|
||||||
|
if expected != actual {
|
||||||
|
t.Errorf("first stack: expected string %q, got %q",
|
||||||
|
expected, actual)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
sta = &Stack{}
|
||||||
|
sta.Push(egAlbum(27))
|
||||||
|
sta.Push(egAlbum(4))
|
||||||
|
sta.Peek()
|
||||||
|
sta.Push(egAlbum(5))
|
||||||
|
sta.Push(egAlbum(6))
|
||||||
|
sta.Push(egAlbum(7))
|
||||||
|
sta.Pop()
|
||||||
|
expected = "[6, 5, 4, 27, ]"
|
||||||
|
actual = sta.String()
|
||||||
|
if expected != actual {
|
||||||
|
t.Errorf("second stack: expected string %q, got %q",
|
||||||
|
expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user