85 lines
2.7 KiB
Go
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()
|
|
}
|