Created
March 16, 2020 02:04
-
-
Save jeremyherbert/c82e2733f0d8e3a1621684bfd38ddb3d to your computer and use it in GitHub Desktop.
fusion360 addin to run python scripts from json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import adsk.core | |
import adsk.fusion | |
import importlib | |
import inspect | |
import traceback | |
import os | |
import sys | |
import gettext | |
import types | |
import tempfile | |
import threading | |
from http.server import HTTPServer, BaseHTTPRequestHandler | |
import json | |
pydevd_path = None | |
ui = None | |
handlers = [] | |
saved_context = None | |
custom_event = None | |
custom_event_name = 'fusion_idea_run_script' | |
THREAD_HANDLE = None | |
script_run_log_path = os.path.join(tempfile.gettempdir(), "f360_script_run_log.txt") | |
class ThreadEventHandler(adsk.core.CustomEventHandler): | |
def __init__(self): | |
super().__init__() | |
def notify(self, args): | |
try: | |
args = json.loads(args.additionalInfo) | |
script_path = os.path.abspath(args['script']) | |
detach = args['detach'] | |
if os.path.isfile(script_path): | |
script_name = os.path.splitext(os.path.basename(script_path))[0] | |
script_dir = os.path.dirname(script_path) | |
sys.path.append(script_dir) | |
try: | |
import attach_script | |
attach_script.attach(args['debug_port'], 'localhost') | |
module = importlib.import_module(script_name) | |
importlib.reload(module) | |
module.run({'isApplicationStartup': False}) | |
finally: | |
del sys.path[-1] | |
if detach: | |
try: | |
import pydevd | |
pydevd.stoptrace() | |
except: | |
pass | |
except: | |
with open(script_run_log_path, 'a') as f: | |
f.write(traceback.format_exc()) | |
class FusionInjectorHTTPRequestHandler(BaseHTTPRequestHandler): | |
def __init__(self, *args, **kwargs): | |
self._pydevd_path = None | |
super().__init__(*args, **kwargs) | |
def do_POST(self): | |
content_length = int(self.headers['Content-Length']) | |
body = self.rfile.read(content_length) | |
try: | |
request_data = json.loads(body.decode()) | |
assert "jetbrains_pydevd_path" in request_data | |
assert "script" in request_data | |
assert "detach" in request_data | |
assert "debug_port" in request_data | |
if self._pydevd_path is None: | |
self._pydevd_path = request_data['jetbrains_pydevd_path'] | |
sys.path.append(os.path.join(self._pydevd_path, 'pydevd_attach_to_process')) | |
sys.path.append(self._pydevd_path) | |
adsk.core.Application.get().fireCustomEvent("fusion_idea_run_script", json.dumps(request_data)) | |
self.send_response(200) | |
self.end_headers() | |
self.wfile.write(b"done") | |
except: | |
self.send_response(500) | |
self.end_headers() | |
self.wfile.write(traceback.format_exc().encode()) | |
def run_server(): | |
server_address = ('localhost', 8181) | |
httpd = HTTPServer(server_address, FusionInjectorHTTPRequestHandler) | |
httpd.serve_forever() | |
def run(context): | |
try: | |
app = adsk.core.Application.get() | |
ui = app.userInterface | |
try: | |
app.unregisterCustomEvent(custom_event_name) | |
except: | |
pass | |
custom_event = app.registerCustomEvent(custom_event_name) | |
event_handler = ThreadEventHandler() | |
custom_event.add(event_handler) | |
handlers.append(event_handler) | |
THREAD_HANDLE = threading.Thread(target=run_server, daemon=True) | |
THREAD_HANDLE.start() | |
ui.messageBox('AddIn Started') | |
except: | |
if ui: | |
ui.messageBox(('AddIn Start Failed: {}').format(traceback.format_exc())) | |
def stop(context): | |
ui = None | |
try: | |
app = adsk.core.Application.get() | |
ui = app.userInterface | |
except: | |
if ui: | |
ui.messageBox(('AddIn Stop Failed: {}').format(traceback.format_exc())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment