Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/gui #1

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Package Application

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
strategy:
matrix:
os: [windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install python requirements
run: |
python3 -m pip install -r ./custom-blender-worker/requirements.txt
python3 -m pip install pyinstaller
- name: Package pyproc
run: |
pushd ./custom-blender-worker/
pyinstaller --collect-all bpy -F ./dcp_custom_blender_worker\main.py -F -n pyproc
popd

- uses: actions/setup-node@v4
with:
node-version: 18
- name: Install npm packages
run: |
pushd ./custom-blender-worker/
npm ci
npm install -g pkg
pkg .\src\index.js -t node18-win -o ./dist/nodeproc.exe
popd

- name: Check binaries
run: |
ls ./custom-blender-worker/dist/
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
build/bin
node_modules
frontend/build
custom-blender-worker/build
custom-blender-worker/dist
node_modules/
.venv/

Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# DCP Custom Blender Worker
# README

Leveraging custom worktimes and the custom-worker base class, we are able to develop a custom blender worktime which enables users to safely render job deployers' scenes without executing untrusted code on their local machine.
## About

This is the official Wails Svelte template.

## Getting Started
## Live Development

To get started, simply run the following:
To run in live development mode, run `wails dev` in the project directory. This will run a Vite development
server that will provide very fast hot reload of your frontend changes. If you want to develop in a browser
and have access to your Go methods, there is also a dev server that runs on http://localhost:34115. Connect
to this in your browser, and you can call your Go code from devtools.

1. `pip install -r ./requirements.txt`
2. `uvicorn dcp_custom_blender_worker.main:app --port 8001`
3. `npm run start`
4. ???
5. Profit 💰💰💰
## Building

To build a redistributable, production mode package, use `wails build`.
197 changes: 197 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package main

import (
"bufio"
"context"
"fmt"
"io"
"log"
"net"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
"sync/atomic"
"syscall"
)

func GetFreePort() (port string, err error) {
var a *net.TCPAddr
if a, err = net.ResolveTCPAddr("tcp", "localhost:0"); err == nil {
var l *net.TCPListener
if l, err = net.ListenTCP("tcp", a); err == nil {
defer l.Close()
port := l.Addr().(*net.TCPAddr).Port
return strconv.Itoa(port), nil
}
}
return
}

// App struct
type App struct {
ctx context.Context
nodeProc *exec.Cmd
pyProc *exec.Cmd
os string
}

// NewApp creates a new App application struct
func NewApp() *App {
os := runtime.GOOS
app := App{os: os}
fmt.Println("OS: ", os)
return &app
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s, It's show time!", name)
}

func (a *App) StartWorker() bool {
if (a.nodeProc != nil) && (a.pyProc != nil) {
return true
}

port, err := GetFreePort()
if err != nil {
panic(err)
}
log.Println("Found free port: ", port)

exLoc, err := os.Executable()
if err != nil {
panic(err)
}
exPath := filepath.Dir(exLoc)
log.Printf("Found path at : %s\n", exPath)

if a.nodeProc == nil {
nodePath := filepath.Join(exPath, "..", a.os, "nodeProc.exe")
log.Printf("Starting node process with: %s %s\n", nodePath, port)
cmd := exec.Command(nodePath, port)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}

stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
log.Fatal(err)
}

err = cmd.Start()

if err != nil {
log.Fatal(err)
}

go LogProcess("Node Process", &stdout, &stderr)

a.nodeProc = cmd
}

if a.pyProc == nil {
pyPath := filepath.Join(exPath, "..", a.os, "pyproc", "pyproc.exe")
log.Printf("Starting node process with: %s\n", pyPath)
cmd := exec.Command(pyPath, "--port", port)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}

stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
log.Fatal(err)
}

err = cmd.Start()

if err != nil {
log.Fatal(err)
}

go LogProcess("Python Process", &stdout, &stderr)

a.pyProc = cmd
}

return true
}

func (a *App) KillWorker() bool {
if (a.nodeProc == nil) && (a.pyProc == nil) {
return true
}

if a.nodeProc != nil {
a.nodeProc.Process.Kill()
a.nodeProc = nil
log.Printf("Killing Node Worker")
}

if a.pyProc != nil {
a.pyProc.Process.Kill()
a.pyProc = nil
log.Printf("Killing Python Worker")
}

return true
}

func LogProcess(processName string, stdout *io.ReadCloser, stderr *io.ReadCloser) {

var wg sync.WaitGroup
var ops atomic.Uint32

outch := make(chan string, 10)

scannerStdout := bufio.NewScanner(*stdout)
wg.Add(1)
go func() {
for scannerStdout.Scan() {
text := scannerStdout.Text()
if strings.TrimSpace(text) != "" {
outch <- text
}
}
ops.Add(1)
wg.Done()
}()

scannerStderr := bufio.NewScanner(*stderr)
wg.Add(1)
go func() {
for scannerStderr.Scan() {
text := scannerStderr.Text()
if strings.TrimSpace(text) != "" {
outch <- text
}
}
ops.Add(1)
wg.Done()
}()

for {
select {
case text := <-outch:
log.Printf("[%s] | %s", processName, text)
}
if ops.Load() >= 1 {
wg.Wait()
break
}
}
}
35 changes: 35 additions & 0 deletions build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Build Directory

The build directory is used to house all the build files and assets for your application.

The structure is:

* bin - Output directory
* darwin - macOS specific files
* windows - Windows specific files

## Mac

The `darwin` directory holds files specific to Mac builds.
These may be customised and used as part of the build. To return these files to the default state, simply delete them
and
build with `wails build`.

The directory contains the following files:

- `Info.plist` - the main plist file used for Mac builds. It is used when building using `wails build`.
- `Info.dev.plist` - same as the main plist file but used when building using `wails dev`.

## Windows

The `windows` directory contains the manifest and rc files used when building with `wails build`.
These may be customised for your application. To return these files to the default state, simply delete them and
build with `wails build`.

- `icon.ico` - The icon used for the application. This is used when building using `wails build`. If you wish to
use a different icon, simply replace this file with your own. If it is missing, a new `icon.ico` file
will be created using the `appicon.png` file in the build directory.
- `installer/*` - The files used to create the Windows installer. These are used when building using `wails build`.
- `info.json` - Application details used for Windows builds. The data here will be used by the Windows installer,
as well as the application itself (right click the exe -> properties -> details)
- `wails.exe.manifest` - The main application manifest file.
Binary file added build/appicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions build/darwin/Info.dev.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>{{.Info.ProductName}}</string>
<key>CFBundleExecutable</key>
<string>{{.Name}}</string>
<key>CFBundleIdentifier</key>
<string>com.wails.{{.Name}}</string>
<key>CFBundleVersion</key>
<string>{{.Info.ProductVersion}}</string>
<key>CFBundleGetInfoString</key>
<string>{{.Info.Comments}}</string>
<key>CFBundleShortVersionString</key>
<string>{{.Info.ProductVersion}}</string>
<key>CFBundleIconFile</key>
<string>iconfile</string>
<key>LSMinimumSystemVersion</key>
<string>10.13.0</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>{{.Info.Copyright}}</string>
{{if .Info.FileAssociations}}
<key>CFBundleDocumentTypes</key>
<array>
{{range .Info.FileAssociations}}
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>{{.Ext}}</string>
</array>
<key>CFBundleTypeName</key>
<string>{{.Name}}</string>
<key>CFBundleTypeRole</key>
<string>{{.Role}}</string>
<key>CFBundleTypeIconFile</key>
<string>{{.IconName}}</string>
</dict>
{{end}}
</array>
{{end}}
{{if .Info.Protocols}}
<key>CFBundleURLTypes</key>
<array>
{{range .Info.Protocols}}
<dict>
<key>CFBundleURLName</key>
<string>com.wails.{{.Scheme}}</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{{.Scheme}}</string>
</array>
<key>CFBundleTypeRole</key>
<string>{{.Role}}</string>
</dict>
{{end}}
</array>
{{end}}
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
</dict>
</plist>
Loading