nori/cmd/bulk-bin/main.go

190 lines
4.5 KiB
Go
Raw Normal View History

2023-01-05 06:41:21 +00:00
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
2024-08-06 03:35:53 +00:00
"log"
"log/slog"
2023-01-05 06:41:21 +00:00
"os"
"path/filepath"
2023-01-05 07:08:48 +00:00
"runtime/pprof"
2023-01-05 06:41:21 +00:00
"strings"
"time"
2024-08-06 03:35:53 +00:00
"anime.bike/slogutil/slogenv"
"anime.bike/stint"
2023-01-05 07:08:48 +00:00
"git.tuxpa.in/a/nori/renderer"
"gitlab.com/gfxlabs/gfximg/apng"
"golang.org/x/sync/errgroup"
2023-01-05 06:41:21 +00:00
"git.tuxpa.in/a/nori"
"git.tuxpa.in/a/nori/utils"
)
var (
dumpPtr = flag.Bool("d", false, "dump nri file to zip")
silentPtr = flag.Bool("s", false, "silent")
bulkDumpPtr = flag.Bool("b", false, "bulk dump nris from a folder")
jsonDumpPtr = flag.Bool("j", false, "bulk dump nri animation names from a folder")
directoryPtr = flag.String("dir", "nri", "directory to bulk dump from")
destinationPtr = flag.String("dest", "", "directory to bulk dump to")
filePtr = flag.String("f", "example.nri", "file to load")
outputPtr = flag.String("o", "output.zip", "output zip file")
2023-01-05 07:08:48 +00:00
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
2023-01-05 06:41:21 +00:00
)
2024-08-06 03:35:53 +00:00
func init() {
slog.SetDefault(slog.New(stint.NewHandler(os.Stderr, &stint.Options{
AddSource: true,
Level: slogenv.EnvLevel(),
})))
}
2023-01-05 06:41:21 +00:00
func main() {
flag.Parse()
2023-01-05 07:08:48 +00:00
if len(os.Args) < 2 {
flag.PrintDefaults()
}
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
panic(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
2023-01-05 06:41:21 +00:00
if *dumpPtr {
filename := *filePtr
output := *outputPtr
if _, err := os.Stat(filename); err != nil {
printIf("could not find file %s\n", filename)
return
}
dump(filename, output)
return
}
dir := *directoryPtr
dest := *destinationPtr
if dest == "" {
dest = dir
}
printIf("output: %s\n", dest)
if *bulkDumpPtr || *jsonDumpPtr {
2023-01-05 07:08:48 +00:00
files, err := os.ReadDir(dir)
2023-01-05 06:41:21 +00:00
if err != nil {
printIf("%s: %s\n", dir, err)
return
}
egg := errgroup.Group{}
egg.SetLimit(12)
for _, ff := range files {
f := ff
if strings.HasSuffix(f.Name(), ".nri") {
egg.Go(func() error {
if *bulkDumpPtr {
2023-01-05 07:08:48 +00:00
if err := dump_nozip(dir+"/"+f.Name(), dest); err != nil {
return err
}
2023-01-05 06:41:21 +00:00
}
if *jsonDumpPtr {
2023-01-05 07:08:48 +00:00
if err := dump_nozip(dir+"/"+f.Name(), dest); err != nil {
return dump_anim_json(dir+"/"+f.Name(), dest)
}
2023-01-05 06:41:21 +00:00
}
return nil
})
}
}
if err := egg.Wait(); err != nil {
log.Panicf("oh fuck: %s\n", err)
return
}
}
}
func printIf(s string, args ...interface{}) {
if !*silentPtr {
fmt.Printf(s, args...)
}
}
2023-01-05 07:08:48 +00:00
func dump_anim_json(filename string, destination string) error {
2023-01-05 06:41:21 +00:00
n, err := nori.FromFile(filename)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("decode: %s", err)
2023-01-05 06:41:21 +00:00
}
names, err := nori.GetAnimationNames(n)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("animation: %s", err)
2023-01-05 06:41:21 +00:00
}
json, err := json.Marshal(names)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("could not marshal json: %s\n", err)
2023-01-05 06:41:21 +00:00
}
baseName := filepath.Base(strings.TrimSuffix(filename, filepath.Ext(filename)))
output := fmt.Sprintf("%s/%s.json", destination, baseName)
2023-01-05 07:08:48 +00:00
return os.WriteFile(output, json, 0o740)
2023-01-05 06:41:21 +00:00
}
2023-01-05 07:08:48 +00:00
func dump_nozip(filename string, destination string) error {
2023-01-05 06:41:21 +00:00
start := time.Now()
n, err := nori.FromFile(filename)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("decode: %s", err)
2023-01-05 06:41:21 +00:00
}
// printIf("rendering %d animation(s)\n", n.AnimationCount)
animations, err := renderer.RenderAnimationsApng(n)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("animation: %s", err)
2023-01-05 06:41:21 +00:00
}
baseName := filepath.Base(strings.TrimSuffix(filename, filepath.Ext(filename)))
for i, v := range animations {
output := fmt.Sprintf(destination+"/%s_%d.png", baseName, i)
// printIf("saving to %s \n", output)
f, fErr := os.OpenFile(output, os.O_CREATE, 0740)
if fErr != nil {
2023-01-05 07:08:48 +00:00
return fErr
2023-01-05 06:41:21 +00:00
}
defer f.Close()
if err := apng.Encode(f, *v); err != nil {
2023-01-05 07:08:48 +00:00
return err
2023-01-05 06:41:21 +00:00
}
}
//
//if err := utils.ZipApngs(out, animations); err != nil {
2023-01-05 07:08:48 +00:00
// return fmt.Errorf("zipping: %s", err)
2023-01-05 06:41:21 +00:00
//}
printIf("done in %v \n", time.Now().Sub(start))
//os.WriteFile(output, out.Bytes(), 0740)
2023-01-05 07:08:48 +00:00
return nil
2023-01-05 06:41:21 +00:00
}
2023-01-05 07:08:48 +00:00
func dump(filename string, output string) error {
2023-01-05 06:41:21 +00:00
start := time.Now()
n, err := nori.FromFile(filename)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("decode: %s", err)
2023-01-05 06:41:21 +00:00
}
out := new(bytes.Buffer)
printIf("rendering %d animation(s)\n", n.AnimationCount)
animations, err := renderer.RenderAnimationsApng(n)
if err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("animation: %s", err)
2023-01-05 06:41:21 +00:00
}
printIf("saving to %s \n", output)
if err := utils.ZipApngs(out, animations); err != nil {
2023-01-05 07:08:48 +00:00
return fmt.Errorf("zipping: %s", err)
2023-01-05 06:41:21 +00:00
}
printIf("done in %v \n", time.Now().Sub(start))
os.WriteFile(output, out.Bytes(), 0740)
2023-01-05 07:08:48 +00:00
return nil
2023-01-05 06:41:21 +00:00
}