diff --git a/Makefile b/Makefile index 90e7aed2..0280c489 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,9 @@ version: @echo "Version: ${VERSION}" @echo "Target : ${OUT}" +embedded: + @go list -f "{{.Name}}: {{.EmbedFiles}}" ${PKG}/... + test: go test -short ${PKG_LIST} diff --git a/go.mod b/go.mod index 9e4e7a3a..a90bd335 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/dop251/goja v0.0.0-20211217115348-3f9136fa235d + github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7 github.com/mattn/go-colorable v0.1.12 github.com/rs/zerolog v1.26.1 ) diff --git a/go.sum b/go.sum index 1855b687..cb9c20d4 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,7 @@ github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dop251/goja v0.0.0-20211217115348-3f9136fa235d h1:XT7Qdmcuwgsgz4GXejX7R5Morysk2GOpeguYJ9JoF5c= github.com/dop251/goja v0.0.0-20211217115348-3f9136fa235d/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7 h1:tYwu/z8Y0NkkzGEh3z21mSWggMg4LwLRFucLS7TjARg= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= diff --git a/job_compilers/job_compilers.go b/job_compilers/job_compilers.go index bd0edb6a..3dba55ce 100644 --- a/job_compilers/job_compilers.go +++ b/job_compilers/job_compilers.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/dop251/goja" + "github.com/dop251/goja_nodejs/require" "github.com/rs/zerolog/log" ) @@ -25,13 +26,37 @@ func Load() (*GojaJobCompiler, error) { return nil, err } + staticFileLoader := func(path string) ([]byte, error) { + content, err := compiler.loadScript(path) + if err != nil { + // The 'require' module uses this to try different variations of the path + // in order to find it (without .js, with .js, etc.), so don't log any of + // such errors. + return nil, require.ModuleFileDoesNotExistError + } + log.Debug().Err(err).Str("path", path).Msg("imported module") + return content, nil + } + + registry := require.NewRegistry(require.WithLoader(staticFileLoader)) // this can be shared by multiple runtimes + registry.Enable(compiler.vm) + + // registry.RegisterNativeModule("pathlib", func(r *goja.Runtime, o *goja.Object) { + // log.Debug().Interface("runtime", r).Interface("object", o).Msg("loading pathlib") + // o.Set("exports", compiler.jobtypes["simple-blender-render"]) + // log.Debug().Interface("exports", o).Msg("exporting") + // }) + return &compiler, nil } func newGojaVM() *goja.Runtime { + vm := goja.New() + vm.SetFieldNameMapper(goja.UncapFieldNameMapper()) + vm.Set("print", func(call goja.FunctionCall) goja.Value { - log.Info().Str("args", call.Argument(0).String()).Msg("print") + log.Info().Interface("args", call.Arguments).Msg("print") return goja.Undefined() }) vm.Set("create_task", func(call goja.FunctionCall) goja.Value { @@ -45,12 +70,53 @@ func newGojaVM() *goja.Runtime { return vm } +type Job struct { + ID int64 + Name string + JobType string + Priority int8 + Settings JobSettings + Metadata JobMetadata +} + +type JobSettings map[string]interface{} +type JobMetadata map[string]string + func (c *GojaJobCompiler) Run(jobType string) error { program, ok := c.jobtypes[jobType] if !ok { return ErrJobTypeUnknown } + job := Job{ + ID: 327, + JobType: "blender-render", + Priority: 50, + Name: "190_0030_A.lighting", + Settings: JobSettings{ + "blender_cmd": "{blender}", + "chunk_size": 5, + "frames": "101-172", + "render_output": "{render}/sprites/farm_output/shots/190_credits/190_0030_A/190_0030_A.lighting/######", + "fps": 24.0, + "extract_audio": false, + "images_or_video": "images", + "format": "OPEN_EXR_MULTILAYER", + "output_file_extension": ".exr", + "filepath": "{shaman}/65/61672427b63a96392cd72d65/pro/shots/190_credits/190_0030_A/190_0030_A.lighting.flamenco.blend", + }, + Metadata: JobMetadata{ + "user": "Sybren A. Stüvel ", + "project": "Sprøte Frøte", + }, + } + c.vm.Set("job", &job) + _, err := c.vm.RunProgram(program) return err } + +func (j *Job) NewTask(call goja.ConstructorCall) goja.Value { + log.Debug().Interface("args", call.Arguments).Msg("job.NewTask") + return goja.Undefined() +} diff --git a/job_compilers/scripts.go b/job_compilers/scripts.go index c6e59c0f..b273dd53 100644 --- a/job_compilers/scripts.go +++ b/job_compilers/scripts.go @@ -11,7 +11,7 @@ import ( "github.com/rs/zerolog/log" ) -//go:embed scripts/*.js +//go:embed scripts var scriptsFS embed.FS func (c *GojaJobCompiler) loadScripts() error { @@ -22,12 +22,8 @@ func (c *GojaJobCompiler) loadScripts() error { for _, script := range scripts { filename := path.Join("scripts", script.Name()) - file, err := scriptsFS.Open(filename) - if err != nil { - return fmt.Errorf("failed to open embedded script: %w", err) - } - script_bytes, err := io.ReadAll(file) + script_bytes, err := c.loadScript(filename) if err != nil { log.Error().Err(err).Str("filename", filename).Msg("failed to read script") continue @@ -48,6 +44,14 @@ func (c *GojaJobCompiler) loadScripts() error { return nil } +func (c *GojaJobCompiler) loadScript(path string) ([]byte, error) { + file, err := scriptsFS.Open(path) + if err != nil { + return nil, fmt.Errorf("failed to open embedded script: %w", err) + } + return io.ReadAll(file) +} + func filenameToJobType(filename string) string { extension := path.Ext(filename) stem := filename[:len(filename)-len(extension)] diff --git a/job_compilers/scripts/node_modules/pathlib.js b/job_compilers/scripts/node_modules/pathlib.js new file mode 100644 index 00000000..64708498 --- /dev/null +++ b/job_compilers/scripts/node_modules/pathlib.js @@ -0,0 +1,7 @@ +function test() { + print('test passed!') +} + +module.exports = { + test: test +} \ No newline at end of file diff --git a/job_compilers/scripts/simple_blender_render.js b/job_compilers/scripts/simple_blender_render.js index bbcd02cf..295744e9 100644 --- a/job_compilers/scripts/simple_blender_render.js +++ b/job_compilers/scripts/simple_blender_render.js @@ -1,8 +1,23 @@ -print("creating tasks"); +print('Blender Render job submitted'); +print('job: ', job) -for (var i = 0; i < 5; i++) { - create_task("task" + i, "task" + i + " description"); -} +var pathlib = require('pathlib'); +print('loaded module') +print('running pathlib.test()') +pathlib.test() -print("done creating tasks"); -alert("je moeder", { id: "hahahahaha" }); +// The render path contains a filename pattern, most likely '######' or +// something similar. This has to be removed, so that we end up with +// the directory that will contain the frames. +const render_output = job.settings.render_output.replace(/[\\\/][^\\\/]*$/, ''); +print('render output', render_output); +// final_dir = self.render_output.parent +// render_dir = intermediate_path(job, self.final_dir) + + + +// for (var i = 0; i < 5; i++) { +// create_task('task' + i, 'task' + i + ' description'); +// } + +print('done creating tasks'); \ No newline at end of file diff --git a/main.go b/main.go index d2bc1b20..f0b49769 100644 --- a/main.go +++ b/main.go @@ -18,5 +18,7 @@ func main() { log.Fatal().Err(err).Msg("error loading job compilers") } - compiler.Run("simple-blender-render") + if err := compiler.Run("simple-blender-render"); err != nil { + log.Fatal().Err(err).Msg("error running job compiler") + } }