badger/internal/library/import.go
2023-03-14 09:53:33 +01:00

85 lines
2.7 KiB
Go

package library
import (
"errors"
"io/fs"
"path"
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"time"
"velvettear/badger/internal/config"
"velvettear/badger/internal/database"
"velvettear/badger/internal/log"
"velvettear/badger/internal/tools"
)
func Import() {
timestamp := tools.LogTimestamp()
importDirectory := config.ImportDirectory()
log.Info("import of directory '" + importDirectory + "' started...")
// find files in import directory
files := findFiles(importDirectory)
if len(files) == 0 {
log.InfoTimed("import of directory '"+importDirectory+"' finished, no files were detected", timestamp)
return
}
// setup waitgroup and communication channels
ipcMove := make(chan wrapper)
ipcStore := make(chan wrapper)
wait := new(sync.WaitGroup)
wait.Add(3)
// parse the files and store the generated metadata asynchronously
go parseFiles(files, ipcMove, wait)
go moveFiles(ipcMove, ipcStore, wait)
go storeMetadata(ipcStore, wait)
wait.Wait()
close(ipcStore)
// persist the in memory database to the filesystem
database.Persist()
// clean up empty directories
deletionErrors := tools.DeleteEmpty(importDirectory)
for _, error := range deletionErrors {
dirNotEmptyError, ok := error.(*fs.PathError)
if !ok || !errors.Is(dirNotEmptyError, syscall.ENOTEMPTY) {
log.Error("encountered an error deleting directory", error.Error())
continue
}
log.Warning("could not delete directy '" + dirNotEmptyError.Path + "' because it's not empty")
}
log.InfoTimed("import of directory '"+importDirectory+"' finished", timestamp)
}
func moveFiles(ipcInput chan wrapper, ipcOutput chan wrapper, wait *sync.WaitGroup) {
timestamp := tools.LogTimestamp()
log.Debug("starting loop to move files according to their metadata...")
moved := 0
for {
wrapper := <-ipcInput
target := path.Join(wrapper.metadata.GenerateTargetPath(), wrapper.metadata.GenerateFileName())
if tools.Exists(target) {
log.Warning("file '" + wrapper.metadata.Path + "' should be moved to already existing location '" + target + "', appending timestamp")
extension := filepath.Ext("." + wrapper.metadata.Path)
target = strings.Replace(target, extension, " [badger "+strconv.FormatInt(time.Now().UnixMilli(), 10)+"]"+extension, -1)
}
// if !wrapper.metadata.ShouldBeMoved(target) {
// continue
// }
// TODO: uncomment for "real usage"
error := tools.MoveFile(wrapper.metadata.Path, target)
if error != nil {
log.Error("encountered an error moving file '"+wrapper.metadata.Path+"' to '"+target+"'", error.Error())
continue
}
moved++
wrapper.metadata.Path = target
ipcOutput <- wrapper
if wrapper.last {
break
}
}
log.InfoTimed("successfully moved "+strconv.Itoa(moved)+" files according to their metadata", timestamp)
wait.Done()
}