⬗ (Osu! Background Manager) A little utility to replace, retrieve or remove backgrounds for every beatmap in your osu! folder ⬖
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
3.0 KiB

package main
import (
"fmt"
"os"
"path/filepath"
"sync"
"time"
"github.com/Unbewohnte/OBM/logger"
"github.com/Unbewohnte/OBM/manager"
"github.com/Unbewohnte/OBM/settings"
)
var (
WG sync.WaitGroup
)
type job struct {
songPath string
pathToImage string
}
type result struct {
successful uint64
failed uint64
}
// a basic implementation of a concurrent worker
func worker(jobs <-chan job, results chan result, WG *sync.WaitGroup) {
defer WG.Done()
for job := range jobs {
s, f := manager.ReplaceBackgrounds(job.songPath, job.pathToImage)
results <- result{
successful: s,
failed: f,
}
}
}
func workerPool(jobs chan job, results chan result, numOfWorkers int, WG *sync.WaitGroup) {
// check if there are less jobs than workers
if numOfWorkers > len(jobs) {
numOfWorkers = len(jobs)
}
// replacing backgrounds for each beatmap concurrently
for i := 0; i < numOfWorkers; i++ {
WG.Add(1)
go worker(jobs, results, WG)
}
}
func init() {
exists, err := settings.CheckSettingsFile()
if err != nil {
logger.LogError(true, err)
}
if exists {
logger.LogInfo("Found settings file")
return
}
// settings file does not exist, so create it and exit (assuming that this is the first run)
settings.CreateSettingsFile()
os.Exit(0)
}
func main() {
startingTime := time.Now()
settings := settings.GetSettings()
// processing given settings
if settings.CreateBlackBGImage {
err := manager.CreateBlackBG(1920, 1080)
if err == nil {
logger.LogInfo("Successfully created black background")
} else {
logger.LogWarning(fmt.Sprintf("Could not create black background : %s; continuing to run...", err))
}
}
osuSongsDir, err := manager.GetSongsDir(settings.OsuDir)
if err != nil {
logger.LogError(true, err)
}
if settings.ReplacementImagePath == "" || settings.ReplacementImagePath == " " {
logger.LogError(true, "Image path not specified ! Specify `pathToimage` in settings file !")
}
// reading contents of `Songs` folder
osuSongsDirContents, err := os.ReadDir(osuSongsDir)
if err != nil {
logger.LogError(true, fmt.Sprintf("Error reading osu songs directory : %s", err.Error()))
}
// creating jobs for workers
jobs := make(chan job, len(osuSongsDirContents))
for _, songDir := range osuSongsDirContents {
if songDir.IsDir() {
jobs <- job{
songPath: filepath.Join(osuSongsDir, songDir.Name()),
pathToImage: settings.ReplacementImagePath,
}
}
}
close(jobs)
logger.LogInfo(fmt.Sprintf("Found %d song folders", len(jobs)))
results := make(chan result, len(jobs))
workerPool(jobs, results, settings.Workers, &WG)
WG.Wait()
close(results)
// extracting results and logging the last message
var successful, failed uint64 = 0, 0
for result := range results {
successful += result.successful
failed += result.failed
}
total := successful + failed
logger.LogInfo(fmt.Sprintf("DONE in %v. %d successful (%d%%/100%%); %d failed (%d%%/100%%)",
time.Since(startingTime), successful, successful/total*100, failed, failed/total*100))
}