Adding project files to project template

This commit is contained in:
2024-03-27 09:55:27 +01:00
parent 23aaf60b09
commit 87105a06c1
22 changed files with 2690 additions and 1 deletions

262
test.py Normal file
View File

@@ -0,0 +1,262 @@
import bpy
import os
import re
import time
from queue import Queue
from threading import Thread, Event
from subprocess import Popen, PIPE, STDOUT
from bpy.types import Panel, Operator, PropertyGroup
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
EnumProperty,
PointerProperty,
CollectionProperty
)
class BlendFileProperty(PropertyGroup):
path = StringProperty(subtype="FILE_PATH")
filename = StringProperty(subtype="FILE_NAME")
blending_enabled = BoolProperty(
name="Enable or Disable",
description="Enable blend file for blending",
default=False)
status = StringProperty(
name="Status",
description="Status of current file",
default=""
)
class PushBlendPullProperties(PropertyGroup):
project_folder = StringProperty(
name="Project folder",
description="Path to project folder",
default="//",
subtype="DIR_PATH"
)
remote_host = StringProperty(
name="Remote host",
description="Address or host of remote",
defaul =""
)
remote_folder = StringProperty(
name="Remote project folder",
description="Path to remote project folder",
default=""
)
blend_file_list = CollectionProperty(type=BlendFileProperty)
upload_status = StringProperty(
name="Upload status",
description="Status of current upload",
default=""
)
class ProjectManagerRefreshBlenFileOperator(Operator):
bl_idname = "wm.pm_refresh_blend"
bl_label = "Refresh Blender Files"
def execute(self, context):
blendFileList = context.window_manager.project_manager.blend_file_list
enabled = []
for blendFile in blendFileList:
if blendFile.blending_enabled:
enabled.append(blendFile.path)
blendFileList.clear()
path = bpy.path.abspath(context.window_manager.project_manager.project_folder)
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(".blend"):
blendFile = blendFileList.add()
blendFile.filename = os.path.splitext(file)[0]
blendFile.path = os.path.join(root, file)
blendFile.name = bpy.path.relpath(blendFile.path)
blendFile.blending_enabled = blendFile.path in enabled
return {'FINISHED'}
class ProjectManagerStartBlend(Operator):
bl_idname = "wm.project_manager"
bl_label = "Start blend"
_timer = None
_queue = None
_worker = None
def execute(self, context):
wm = context.window_manager
self._queue = Queue()
self._worker = RemoteThreadHandler(
self._queue,
wm.project_manager.blend_file_list,
bpy.path.abspath(wm.project_manager.project_folder),
wm.project_manager.remote_host,
wm.project_manager.remote_folder
)
self._worker.start()
self._timer = wm.event_timer_add(1, context.window)
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def modal(self, context, event):
if event.type in {'ESC'}:
self.cancel(context)
print("canceled")
return {'CANCELLED'}
if event.type == 'TIMER':
while not self._queue.empty():
self.handle_message(self._queue.get(), context.window_manager.project_manager)
self._queue.task_done()
if not self._worker.is_alive():
self.cancel(context)
print("finished")
return {'FINISHED'}
return {'PASS_THROUGH'}
def cancel(self, context):
wm = context.window_manager
wm.event_timer_remove(self._timer)
self._worker.stop()
def handle_message(self, msg, pm):
if msg[0] == "push":
print(msg)
pm.upload_status = "push "+msg[1]
elif msg[0] == "pull":
msg[2].status = "pull "+msg[1]
elif msg[0] == "blend":
msg[2].status = "blend "+msg[1]
class RemoteThreadHandler(Thread):
def __init__(self, q, blendFileList, localFolder, remoteHost, remoteFolder):
super(RemoteThreadHandler, self).__init__()
self._queue = q
self.blendFileList = blendFileList
self.remotePath = "{}:{}".format(remoteHost,remoteFolder)
self.localFolder = localFolder
self.remoteHost = remoteHost
self.remoteFolder = remoteFolder
self._stop_event = Event()
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
ARGS_PUSH = "rsync -azP --info=progress2 --exclude '*.blend1' --exclude 'README.md' {} {}"
ARGS_PULL = "rsync -azP --info=progress2 --exclude '*.blend' {} {}"
ARGS_BLEND = "ssh -t hawat 'blender -b {} -a'"
REGEX_PUSHPULL_STATUS = "\d+%"
def handleLinePush(self, line, current_file=None):
if line == 'end':
self._queue.put(("push", "end",))
return
t = re.search(self.REGEX_PUSHPULL_STATUS, line)
if t is not None:
self._queue.put(("push", t[0],))
def handleLinePull(self, line, current_file):
if line == 'end':
self._queue.put(("pull", "end", current_file,))
return
t = re.search(self.REGEX_PUSHPULL_STATUS, line)
if t is not None:
self._queue.put(("pull", t[0], current_file,))
def run(self):
self.start_process_handle_queue(self.ARGS_PUSH.format(self.localFolder, self.remotePath), self.handleLinePush)
for blendFile in self.blendFileList:
if blendFile.blending_enabled:
remoteBlendFilePath = blendFile.path.replace(self.localFolder, self.remoteFolder)
self.start_process_handle_queue(self.ARGS_BLEND.format(remoteBlendFilePath), self.handleLineBlend, blendFile)
pullWorker = Thread(
target=self.start_process_handle_queue,
args=(self.ARGS_PULL.format(self.remotePath, self.localFolder) , self.handleLinePull, blendFile)
)
pullWorker.start()
def start_process_handle_queue(self, args, lineHandler, current_file = None):
if self.stopped():
return
print(args)
p = Popen(args, shell=True, stdout=PIPE, stderr=STDOUT, universal_newlines=True, bufsize=1)
last_line = ''
while not self.stopped():
line = p.stdout.readline()
if line == '':
if p.poll() is not None:
break
elif line != last_line:
lineHandler(line, current_file)
last_line = line
if self.stopped():
p.kill()
lineHandler('end', current_file)
class ProjectManagerPanel(Panel):
bl_idname = "OBJECT_PT_project_manager"
bl_label = "Project Management"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = ""
def draw(self, context):
layout = self.layout
layout.operator(ProjectManagerStartBlend.bl_idname)
configuration = context.window_manager.project_manager
layout.label(text="Configuration")
layout = self.layout
row = layout.row(align=True)
row.prop(configuration, "project_folder")
row = layout.row(align=True)
row.prop(configuration, "remote_host")
row = layout.row(align=True)
row.prop(configuration, "remote_folder")
row = layout.row(align=True)
row.prop(configuration, "upload_status")
layout.operator(ProjectManagerRefreshBlenFileOperator.bl_idname)
fileList = configuration.blend_file_list
for blendFile in sorted(fileList.values(), key=lambda file: file.path):
row = layout.row()
row.prop(blendFile, "blending_enabled", text=bpy.path.relpath(blendFile.path))
row.prop(blendFile, "status", text="")
def register():
bpy.utils.register_module(__name__)
bpy.types.WindowManager.project_manager = PointerProperty(type=ProjectManagerProperties)
def unregister():
bpy.utils.unregister_module(__name__)
del bpy.types.WindowManager.project_manage
if __name__ == "__main__":
register()