Compare commits

..

No commits in common. "c35f74ea03ac7c82b25576eda2c6a662499a3bd7" and "82efc8994e76826571e7c7a7e8d99b707213821b" have entirely different histories.

4 changed files with 13 additions and 65 deletions

2
.gitignore vendored
View file

@ -1 +1 @@
id3tool tagcleaner

4
.vscode/launch.json vendored
View file

@ -9,9 +9,7 @@
"program": "${workspaceFolder}/main.go", "program": "${workspaceFolder}/main.go",
"args": [ "args": [
"--debug", "--debug",
"--timeout", "/home/velvettear/downloads/test"
"5",
"/tmp/share/music"
] ]
} }
] ]

View file

@ -2,7 +2,6 @@ package config
import ( import (
"os" "os"
"strconv"
"strings" "strings"
"git.velvettear.de/velvettear/loggo" "git.velvettear.de/velvettear/loggo"
@ -10,7 +9,6 @@ import (
var Directory string var Directory string
var FramesToKeep []string var FramesToKeep []string
var Timeout int
// check program arguments and set variables accordingly // check program arguments and set variables accordingly
func CheckArguments() { func CheckArguments() {
@ -26,10 +24,6 @@ func CheckArguments() {
fallthrough fallthrough
case "--frames": case "--frames":
framesToKeep = strings.Split(os.Args[index+1], ",") framesToKeep = strings.Split(os.Args[index+1], ",")
case "-t":
fallthrough
case "--timeout":
Timeout, _ = strconv.Atoi(os.Args[index+1])
case "-h": case "-h":
fallthrough fallthrough
case "--help": case "--help":
@ -44,9 +38,6 @@ func CheckArguments() {
FramesToKeep = append(FramesToKeep, strings.ToUpper(strings.TrimSpace(frame))) FramesToKeep = append(FramesToKeep, strings.ToUpper(strings.TrimSpace(frame)))
} }
} }
if Timeout <= 0 {
Timeout = 30
}
} }
// print the help // print the help

63
main.go
View file

@ -5,10 +5,8 @@ import (
"io/fs" "io/fs"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"git.velvettear.de/velvettear/id3tool/internal/config" "git.velvettear.de/velvettear/id3tool/internal/config"
@ -16,12 +14,6 @@ import (
"github.com/bogem/id3v2/v2" "github.com/bogem/id3v2/v2"
) )
var taskLimiter = make(chan struct{}, runtime.NumCPU())
var taskCommunication = make(chan task)
var waitGroup = sync.WaitGroup{}
var counter int
var taskState = make(map[int]task)
func main() { func main() {
loggo.SetLogFormat("[$LOGLEVEL$] > $MESSAGE$ ($EXTRAS$) [$TIMEDIFF$]") loggo.SetLogFormat("[$LOGLEVEL$] > $MESSAGE$ ($EXTRAS$) [$TIMEDIFF$]")
@ -39,66 +31,39 @@ func main() {
} }
filepath.WalkDir(config.Directory, filterValidFiles) filepath.WalkDir(config.Directory, filterValidFiles)
waitGroup.Wait()
} }
func filterValidFiles(path string, dir fs.DirEntry, err error) error { func filterValidFiles(path string, dir fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
tmp := filepath.Clean(path)
loggo.Debug(tmp)
extension := filepath.Ext(path) extension := filepath.Ext(path)
if dir.IsDir() || (extension != ".flac" && extension != ".mp3") { if dir.IsDir() || (extension != ".flac" && extension != ".mp3") {
return nil return nil
} }
cleanFrames(path)
counter++
waitGroup.Add(1)
taskLimiter <- struct{}{}
tmp := task{counter, path, false}
go func(tmp task) {
go func(tmp task) {
time.Sleep(time.Duration(config.Timeout) * time.Second)
tmp.timeout = true
taskCommunication <- tmp
<-taskLimiter
}(tmp)
cleanFrames(tmp.id, tmp.file)
tmp.timeout = false
taskCommunication <- tmp
<-taskLimiter
}(tmp)
result := <-taskCommunication
check := taskState[result.id]
if check.id == 0 {
taskState[result.id] = result
if result.timeout {
loggo.Warning("(" + strconv.Itoa(result.id) + ") cleaning of file's '" + result.file + "' id3 tags timed out")
}
}
waitGroup.Done()
return nil return nil
} }
func cleanFrames(id int, file string) { func cleanFrames(file string) {
if len(file) == 0 { if len(file) == 0 {
return return
} }
timestamp := time.Now() timestamp := time.Now()
loggo.Info("(" + strconv.Itoa(id) + ") cleaning file's '" + file + "' id3 tags...") loggo.Info("cleaning file's '" + file + "' id3 tags...")
tag, err := id3v2.Open(file, id3v2.Options{Parse: true}) tag, err := id3v2.Open(file, id3v2.Options{Parse: true})
if err != nil { if err != nil {
loggo.Error("("+strconv.Itoa(id)+") encountered an error opening the file '"+file+"' for reading the id3 tags", err.Error()) loggo.Error("encountered an error opening the file '"+file+"' for reading the id3 tags", err.Error())
return return
} }
defer tag.Close() defer tag.Close()
deleted := 0 deleted := 0
for key := range tag.AllFrames() { for key, _ := range tag.AllFrames() {
filter := frameFilter(key) filter := frameFilter(key)
if !filter { if !filter {
continue continue
@ -108,16 +73,16 @@ func cleanFrames(id int, file string) {
} }
if deleted > 0 { if deleted > 0 {
loggo.Debug("(" + strconv.Itoa(id) + ") saving modified id3 tags (" + strconv.Itoa(deleted) + " deleted) to file '" + file + "'...") loggo.Debug("saving modified id3 tags (" + strconv.Itoa(deleted) + " deleted) to file '" + file + "'...")
err := tag.Save() err := tag.Save()
if err != nil { if err != nil {
loggo.Error("("+strconv.Itoa(id)+") encountered an error saving the modified id3 tags to file '"+file+"'", err.Error()) loggo.Error("encountered an error saving the modified id3 tags to file '"+file+"'", err.Error())
return return
} }
loggo.DebugTimed("("+strconv.Itoa(id)+") deleted "+strconv.Itoa(deleted)+" tag(s) from file '"+file+"'", timestamp.UnixMilli()) loggo.DebugTimed("deleted "+strconv.Itoa(deleted)+" tags", timestamp.UnixMilli())
} }
loggo.DebugTimed("("+strconv.Itoa(id)+") finished cleaning file's '"+file+"' id3 tags", timestamp.UnixMilli()) loggo.DebugTimed("finished cleaning file", timestamp.UnixMilli())
} }
func frameFilter(frame string) bool { func frameFilter(frame string) bool {
@ -128,9 +93,3 @@ func frameFilter(frame string) bool {
} }
return true return true
} }
type task struct {
id int
file string
timeout bool
}