diff options
-rw-r--r-- | render_renderfarmfi/__init__.py | 224 | ||||
-rw-r--r-- | render_renderfarmfi/exceptions.py | 41 | ||||
-rw-r--r-- | render_renderfarmfi/operators.py | 347 | ||||
-rw-r--r-- | render_renderfarmfi/ore_session.py | 40 | ||||
-rw-r--r-- | render_renderfarmfi/panels.py | 274 | ||||
-rw-r--r-- | render_renderfarmfi/prepare.py | 189 | ||||
-rw-r--r-- | render_renderfarmfi/rpc.py | 198 | ||||
-rw-r--r-- | render_renderfarmfi/upload.py | 193 | ||||
-rw-r--r-- | render_renderfarmfi/utils.py | 137 |
9 files changed, 0 insertions, 1643 deletions
diff --git a/render_renderfarmfi/__init__.py b/render_renderfarmfi/__init__.py deleted file mode 100644 index 40c601be..00000000 --- a/render_renderfarmfi/__init__.py +++ /dev/null @@ -1,224 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -bl_info = { - "name": "Renderfarm.fi", - "author": "Nathan Letwory <nathan@letworyinteractive.com>, " - "Jesse Kaukonen <jesse.kaukonen@gmail.com>", - "version": (23,), - "blender": (2, 63, 0), - "location": "Render > Engine > Renderfarm.fi", - "description": "Send .blend as session to http://www.renderfarm.fi to render", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Render/Renderfarm.fi", - "category": "Render", -} - -""" -Copyright 2009-2013 Laurea University of Applied Sciences -Authors: Nathan Letwory, Jesse Kaukonen -""" - -import bpy -import hashlib -import http.client -import math -from os.path import isabs, isfile, join, exists -import os -import time - -from bpy.props import PointerProperty, StringProperty, BoolProperty, EnumProperty, IntProperty, CollectionProperty - -from .panels import * -from .operators import * -from .rpc import RffiRpc - -bpy.CURRENT_VERSION = bl_info["version"][0] -bpy.found_newer_version = False -bpy.up_to_date = False -bpy.download_location = 'http://www.renderfarm.fi/blender' - -bpy.rffi_creds_found = False -bpy.rffi_user = '' -bpy.rffi_hash = '' -bpy.passwordCorrect = False -bpy.loginInserted = False -bpy.rffi_accepting = False -bpy.rffi_motd = '' - -bpy.errorMessages = { - 'missing_desc': 'You need to enter a title, short and long description', - 'missing_creds': 'You haven\'t entered your credentials yet' -} - -bpy.statusMessage = { - 'title': 'TRIA_RIGHT', - 'shortdesc': 'TRIA_RIGHT', - 'tags': 'TRIA_RIGHT', - 'longdesc': 'TRIA_RIGHT', - 'username': 'TRIA_RIGHT', - 'password': 'TRIA_RIGHT' -} - -bpy.errors = [] -bpy.ore_sessions = [] -bpy.ore_completed_sessions = [] -bpy.ore_active_sessions = [] -bpy.ore_rejected_sessions = [] -bpy.ore_pending_sessions = [] -bpy.ore_active_session_queue = [] -bpy.ore_complete_session_queue = [] -bpy.queue_selected = -1 -bpy.errorStartTime = -1.0 -bpy.infoError = False -bpy.cancelError = False -bpy.texturePackError = False -bpy.linkedFileError = False -bpy.uploadInProgress = False -try: - bpy.originalFileName = bpy.data.filepath -except: - bpy.originalFileName = 'untitled.blend' -bpy.particleBakeWarning = False -bpy.childParticleWarning = False -bpy.simulationWarning = False -bpy.file_format_warning = False -bpy.ready = False - - -def renderEngine(render_engine): - bpy.utils.register_class(render_engine) - return render_engine - -licenses = ( - ('1', 'CC by-nc-nd', 'Creative Commons: Attribution Non-Commercial No Derivatives'), - ('2', 'CC by-nc-sa', 'Creative Commons: Attribution Non-Commercial Share Alike'), - ('3', 'CC by-nd', 'Creative Commons: Attribution No Derivatives'), - ('4', 'CC by-nc', 'Creative Commons: Attribution Non-Commercial'), - ('5', 'CC by-sa', 'Creative Commons: Attribution Share Alike'), - ('6', 'CC by', 'Creative Commons: Attribution'), - ('7', 'Copyright', 'Copyright, no license specified'), - ) - -class ORESession(bpy.types.PropertyGroup): - name = StringProperty(name='Name', description='Name of the session', maxlen=128, default='[session]') - -class ORESettings(bpy.types.PropertyGroup): - username = StringProperty(name='E-mail', description='E-mail for Renderfarm.fi', maxlen=256, default='') - password = StringProperty(name='Password', description='Renderfarm.fi password', maxlen=256, default='') - - shortdesc = StringProperty(name='Short description', description='A short description of the scene (100 characters)', maxlen=101, default='-') - tags = StringProperty(name='Tags', description='A list of tags that best suit the animation', maxlen=102, default='') - longdesc = StringProperty(name='Description', description='Description of the scene (2k)', maxlen=2048, default='') - title = StringProperty(name='Title', description='Title for this session (128 characters)', maxlen=128, default='') - url = StringProperty(name='Project URL', description='Project URL. Leave empty if not applicable', maxlen=256, default='') - engine = StringProperty(name='Engine', description='The rendering engine that is used for rendering', maxlen=64, default='blender') - samples = IntProperty(name='Samples', description='Number of samples that is used (Cycles only)', min=1, max=1000000, soft_min=1, soft_max=100000, default=100) - subsamples = IntProperty(name='Subsample Frames', description='Number of subsample frames that is used (Cycles only)', min=1, max=1000000, soft_min=1, soft_max=1000, default=10) - file_format = StringProperty(name='File format', description='File format used for the rendering', maxlen=30, default='PNG_FORMAT') - - parts = IntProperty(name='Parts/Frame', description='', min=1, max=1000, soft_min=1, soft_max=64, default=1) - resox = IntProperty(name='Resolution X', description='X of render', min=1, max=10000, soft_min=1, soft_max=10000, default=1920) - resoy = IntProperty(name='Resolution Y', description='Y of render', min=1, max=10000, soft_min=1, soft_max=10000, default=1080) - memusage = IntProperty(name='Memory Usage', description='Estimated maximum memory usage during rendering in MB', min=1, max=6*1024, soft_min=1, soft_max=3*1024, default=256) - start = IntProperty(name='Start Frame', description='Start Frame', default=1) - end = IntProperty(name='End Frame', description='End Frame', default=250) - fps = IntProperty(name='FPS', description='FPS', min=1, max=120, default=25) - - prepared = BoolProperty(name='Prepared', description='Set to True if preparation has been run', default=False) - debug = BoolProperty(name='Debug', description='Verbose output in console', default=False) - selected_session = IntProperty(name='Selected Session', description='The selected session', default=0) - hasUnsupportedSimulation = BoolProperty(name='HasSimulation', description='Set to True if therea re unsupported simulations', default=False) - - inlicense = EnumProperty(items=licenses, name='Scene license', description='License speficied for the source files', default='1') - outlicense = EnumProperty(items=licenses, name='Product license', description='License speficied for the output files', default='1') - sessions = CollectionProperty(type=ORESession, name='Sessions', description='Sessions on Renderfarm.fi') - completed_sessions = CollectionProperty(type=ORESession, name='Completed sessions', description='Sessions that have been already rendered') - rejected_sessions = CollectionProperty(type=ORESession, name='Rejected sessions', description='Sessions that have been rejected') - pending_sessions = CollectionProperty(type=ORESession, name='Pending sessions', description='Sessions that are waiting for approval') - active_sessions = CollectionProperty(type=ORESession, name='Active sessions', description='Sessions that are currently rendering') - all_sessions = CollectionProperty(type=ORESession, name='All sessions', description='List of all of the users sessions') - -# session struct - - -class RENDERFARM_MT_Session(bpy.types.Menu): - bl_label = "Show Session" - - def draw(self, context): - layout = self.layout - ore = context.scene.ore_render - - if (bpy.loginInserted == True): - layout.operator('ore.completed_sessions') - layout.operator('ore.accept_sessions') - layout.operator('ore.active_sessions') - layout.separator() - layout.operator('ore.cancelled_sessions') - else: - row = layout.row() - row.label(text="You must login first") - - -class RenderfarmFi(bpy.types.RenderEngine): - bl_idname = 'RENDERFARMFI_RENDER' - bl_label = "Renderfarm.fi" - - def render(self, scene): - print('Do test renders with Blender Render') - -def register(): - bpy.utils.register_module(__name__) - bpy.types.Scene.ore_render = PointerProperty(type=ORESettings, name='ORE Render', description='ORE Render Settings') - -def unregister(): - bpy.utils.unregister_module(__name__) - -if __name__ == "__main__": - register() - -# all panels, except render panel -# Example of wrapping every class 'as is' -from bl_ui import properties_scene -for member in dir(properties_scene): - subclass = getattr(properties_scene, member) - try: subclass.COMPAT_ENGINES.add('RENDERFARMFI_RENDER') - except: pass -del properties_scene - -from bl_ui import properties_world -for member in dir(properties_world): - subclass = getattr(properties_world, member) - try: subclass.COMPAT_ENGINES.add('RENDERFARMFI_RENDER') - except: pass -del properties_world - -from bl_ui import properties_material -for member in dir(properties_material): - subclass = getattr(properties_material, member) - try: subclass.COMPAT_ENGINES.add('RENDERFARMFI_RENDER') - except: pass -del properties_material - -from bl_ui import properties_object -for member in dir(properties_object): - subclass = getattr(properties_object, member) - try: subclass.COMPAT_ENGINES.add('RENDERFARMFI_RENDER') - except: pass -del properties_object diff --git a/render_renderfarmfi/exceptions.py b/render_renderfarmfi/exceptions.py deleted file mode 100644 index 4d62562c..00000000 --- a/render_renderfarmfi/exceptions.py +++ /dev/null @@ -1,41 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -class RenderfarmException(Exception): - def __init__(self, msg="no reason given"): - self.message = msg - def __str__(self): - return "RenderfarmException: "+self.message - -class LoginFailedException(Exception): - def __init__(self, msg="no reason given"): - self.message = msg - def __str__(self): - return "Login failed: "+self.message - -class SessionCancelFailedException(Exception): - def __init__(self, msg="no reason given"): - self.message = msg - def __str__(self): - return "Session could not be cancelled: "+self.message - -class GetSessionsFailedException(Exception): - def __init__(self, msg="no reason given"): - self.message = msg - def __str__(self): - return "Session List could not be fetched: "+self.message diff --git a/render_renderfarmfi/operators.py b/render_renderfarmfi/operators.py deleted file mode 100644 index 2c867934..00000000 --- a/render_renderfarmfi/operators.py +++ /dev/null @@ -1,347 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import hashlib - -import bpy - -from .utils import _write_credentials, _read_credentials -from .prepare import _prepare_scene -from .upload import _ore_upload -from .rpc import rffi, _do_refresh -from .exceptions import LoginFailedException, SessionCancelFailedException - -class OpSwitchRenderfarm(bpy.types.Operator): - bl_label = "Switch to Renderfarm.fi" - bl_idname = "ore.switch_to_renderfarm_render" - - def execute(self, context): - ore = bpy.context.scene.ore_render - rd = bpy.context.scene.render - - ore.resox = rd.resolution_x - ore.resoy = rd.resolution_y - ore.fps = rd.fps - ore.start = bpy.context.scene.frame_start - ore.end = bpy.context.scene.frame_end - if (rd.engine == 'CYCLES'): - ore.samples = bpy.context.scene.cycles.samples - ore.engine = 'cycles' - else: - ore.engine = 'blender' - bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' - return {'FINISHED'} - -class OpSwitchBlenderRender(bpy.types.Operator): - bl_label = "Switch to local render" - bl_idname = "ore.switch_to_local_render" - - def execute(self, context): - rd = bpy.context.scene.render - ore = bpy.context.scene.ore_render - rd.resolution_x = ore.resox - rd.resolution_y = ore.resoy - rd.fps = ore.fps - bpy.context.scene.frame_start = ore.start - bpy.context.scene.frame_end = ore.end - if (bpy.context.scene.ore_render.engine == 'cycles'): - rd.engine = 'CYCLES' - bpy.context.scene.cycles.samples = ore.samples - else: - bpy.context.scene.render.engine = 'BLENDER_RENDER' - return {'FINISHED'} - -# Copies start & end frame + others from render settings to ore settings -class OpCopySettings(bpy.types.Operator): - bl_label = "Copy settings from current scene" - bl_idname = "ore.copy_settings" - - def execute(self, context): - sce = bpy.context.scene - rd = sce.render - ore = sce.ore_render - ore.resox = rd.resolution_x - ore.resoy = rd.resolution_y - ore.start = sce.frame_start - ore.end = sce.frame_end - ore.fps = rd.fps - return {'FINISHED'} - -class ORE_RefreshOp(bpy.types.Operator): - bl_idname = 'ore.refresh_session_list' - bl_label = 'Refresh' - - def execute(self, context): - result = _do_refresh(self) - if (result == 0): - return {'FINISHED'} - else: - return {'CANCELLED'} - -class ORE_OpenDownloadLocation(bpy.types.Operator): - bl_idname = 'ore.open_download_location' - bl_label = 'Download new version for your platform' - - def execute(self, context): - import webbrowser - webbrowser.open(bpy.download_location) - return {'FINISHED'} - -class ORE_CancelSession(bpy.types.Operator): - bl_idname = 'ore.cancel_session' - bl_label = 'Cancel Session' - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - if len(bpy.ore_complete_session_queue)>0: - s = bpy.ore_complete_session_queue[ore.selected_session] - try: - rffi.cancel_session(self, s) - except SessionCancelFailedException as scfe: - print("sessioncancelfailedexception", scfe) - - return {'FINISHED'} - -class ORE_GetCompletedSessions(bpy.types.Operator): - bl_idname = 'ore.completed_sessions' - bl_label = 'Completed sessions' - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - bpy.queue_selected = 1 - bpy.ore_active_session_queue = bpy.ore_completed_sessions - update_session_list(completed_sessions, ore) - - return {'FINISHED'} - -class ORE_GetCancelledSessions(bpy.types.Operator): - bl_idname = 'ore.cancelled_sessions' - bl_label = 'Cancelled sessions' - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - bpy.queue_selected = 4 - bpy.ore_active_session_queue = bpy.ore_cancelled_sessions - update_session_list(cancelled_sessions, ore) - - return {'FINISHED'} - -class ORE_GetActiveSessions(bpy.types.Operator): - bl_idname = 'ore.active_sessions' - bl_label = 'Rendering sessions' - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - bpy.queue_selected = 2 - bpy.ore_active_session_queue = bpy.ore_active_sessions - update_session_list(active_sessions, ore) - - return {'FINISHED'} - -class ORE_GetPendingSessions(bpy.types.Operator): - bl_idname = 'ore.accept_sessions' # using ORE lingo in API. acceptQueue is session waiting for admin approval - bl_label = 'Pending sessions' - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - bpy.queue_selected = 3 - bpy.ore_active_session_queue = bpy.ore_pending_sessions - update_session_list(pending_sessions, ore) - - return {'FINISHED'} - -class ORE_CheckUpdate(bpy.types.Operator): - bl_idname = 'ore.check_update' - bl_label = 'Check for a new version' - - def execute(self, context): - blenderproxy = xmlrpc.client.ServerProxy(r'http://xmlrpc.renderfarm.fi/renderfarmfi/blender', verbose=bpy.RFFI_VERBOSE) - try: - self.report({'INFO'}, 'Checking for newer version on Renderfarm.fi') - dl_url = blenderproxy.blender.getCurrentVersion(bpy.CURRENT_VERSION) - if len(dl_url['url']) > 0: - self.report({'INFO'}, 'Found a newer version on Renderfarm.fi ' + dl_url['url']) - bpy.download_location = dl_url['url'] - bpy.found_newer_version = True - else: - bpy.up_to_date = True - self.report({'INFO'}, 'Done checking for newer version on Renderfarm.fi') - except xmlrpc.client.Fault as f: - print('ERROR:', f) - self.report({'ERROR'}, 'An error occurred while checking for newer version on Renderfarm.fi: ' + f.faultString) - except xmlrpc.client.ProtocolError as e: - print('ERROR:', e) - self.report({'ERROR'}, 'An HTTP error occurred while checking for newer version on Renderfarm.fi: ' + str(e.errcode) + ' ' + e.errmsg) - - return {'FINISHED'} - -class ORE_LoginOp(bpy.types.Operator): - bl_idname = 'ore.login' - bl_label = 'Login' - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - - ore.password = ore.password.strip() - ore.username = ore.username.strip() - - print("writing new credentials") - _write_credentials(hashlib.md5(ore.password.encode() + ore.username.encode()).hexdigest(),ore.username) - _read_credentials() - ore.password = '' - ore.username = '' - bpy.loginInserted = False - bpy.passwordCorrect = False - - try: - _do_refresh(self, True) - - bpy.passwordCorrect = True - bpy.loginInserted = True - - except LoginFailedException as v: - bpy.ready = False - bpy.loginInserted = False - bpy.passwordCorrect = False - ore.username = bpy.rffi_user - _write_credentials('', '') - _read_credentials() - ore.hash = '' - ore.password = '' - self.report({'WARNING'}, "Incorrect login: " + str(v)) - print(v) - return {'CANCELLED'} - - return {'FINISHED'} - -class ORE_ResetOp(bpy.types.Operator): - bl_idname = "ore.reset" - bl_label = "Reset Preparation" - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - ore.prepared = False - bpy.loginInserted = False - bpy.prepared = False - ore.hash = '' - ore.username = '' - ore.passowrd = '' - ore.longdesc = '' - ore.shortdesc = '-' - ore.tags = '' - ore.title = '' - ore.url = '' - - return {'FINISHED'} - -class ORE_TestRenderOp(bpy.types.Operator): - bl_idname = "ore.test_render" - bl_label = "Run a test render" - - def execute(self, context): - rd = context.scene.render - rd.engine = 'BLENDER_RENDER' - rd.threads_mode = 'AUTO' - rd.threads = 1 - bpy.ops.render.render() - rd.threads_mode = 'FIXED' - rd.threads = 1 - rd.engine = 'RENDERFARMFI_RENDER' - return {'FINISHED'} - -class ORE_UploaderOp(bpy.types.Operator): - bl_idname = "ore.upload" - bl_label = "Render on Renderfarm.fi" - - def execute(self, context): - - bpy.uploadInProgress = True - _prepare_scene() - - returnValue = _ore_upload(self, context) - bpy.uploadInProgress = False - return returnValue - -class ORE_UseBlenderReso(bpy.types.Operator): - bl_idname = "ore.use_scene_settings" - bl_label = "Use Scene settings" - - def execute(self, context): - sce = context.scene - ore = sce.ore_render - rd = context.scene.render - - ore.resox = rd.resolution_x - ore.resoy = rd.resolution_y - ore.start = sce.frame_start - ore.end = sce.frame_end - ore.fps = rd.fps - - return {'FINISHED'} - -class ORE_UseCyclesRender(bpy.types.Operator): - bl_idname = "ore.use_cycles_render" - bl_label = "Cycles" - - def execute(self, context): - context.scene.ore_render.engine = 'cycles' - return {'FINISHED'} - -class ORE_UseBlenderRender(bpy.types.Operator): - bl_idname = "ore.use_blender_render" - bl_label = "Blender Internal" - - def execute(self, context): - context.scene.ore_render.engine = 'blender' - return {'FINISHED'} - -class ORE_ChangeUser(bpy.types.Operator): - bl_idname = "ore.change_user" - bl_label = "Change user" - - def execute(self, context): - ore = context.scene.ore_render - _write_credentials('', '') - _read_credentials() - ore.password = '' - bpy.ore_sessions = [] - ore.hash = '' - bpy.rffi_user = '' - bpy.rffi_hash = '' - bpy.rffi_creds_found = False - bpy.passwordCorrect = False - bpy.loginInserted = False - bpy.rffi_accepts = False - bpy.rffi_motd = '' - - return {'FINISHED'} - -class ORE_CheckStatus(bpy.types.Operator): - bl_idname = "ore.check_status" - bl_label = "Check Renderfarm.fi Accept status" - - def execute(self, context): - rffi.check_status() - return {'FINISHED'} diff --git a/render_renderfarmfi/ore_session.py b/render_renderfarmfi/ore_session.py deleted file mode 100644 index 0f8cc4ef..00000000 --- a/render_renderfarmfi/ore_session.py +++ /dev/null @@ -1,40 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -from math import floor - -class OreSession: - - def __init__(self, id, title): - self.id = id - self.title = title - self.frames = 0 - self.startframe = 0 - self.endframe = 0 - self.rendertime = 0 - self.percentage = 0 - - def percentageComplete(self): - totFrames = self.endframe - self.startframe - done = 0 - if totFrames != 0: - done = floor((self.frames / totFrames)*100) - - if done > 100: - done = 100 - return done diff --git a/render_renderfarmfi/panels.py b/render_renderfarmfi/panels.py deleted file mode 100644 index 117df785..00000000 --- a/render_renderfarmfi/panels.py +++ /dev/null @@ -1,274 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import bpy -import time - -from .utils import _read_credentials, check_status -from .rpc import rffi -from .exceptions import LoginFailedException - -class RenderButtonsPanel(): - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "render" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - -class EngineSelectPanel(RenderButtonsPanel, bpy.types.Panel): - bl_idname = "OBJECT_PT_engineSelectPanel" - bl_label = "Choose rendering mode" - COMPAT_ENGINES = set(['RENDERFARMFI_RENDER']) - - def draw(self, context): - layout = self.layout - row = layout.row() - row.operator("ore.switch_to_renderfarm_render", text="Renderfarm.fi", icon='WORLD') - row.operator("ore.switch_to_local_render", text="Local computer", icon='BLENDER') - -class LOGIN_PT_RenderfarmFi(RenderButtonsPanel, bpy.types.Panel): - bl_label = 'Login to Renderfarm.fi' - COMPAT_ENGINES = set(['RENDERFARMFI_RENDER']) - - @classmethod - def poll(cls, context): - rd = context.scene.render - return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - - # login - if not bpy.loginInserted: - if _read_credentials(): - try: - if rffi.login(None, True, False): - bpy.passwordCorrect = True - bpy.loginInserted = True - except LoginFailedException: - bpy.passwordCorrect = False - bpy.loginInserted = False - - layout = self.layout - ore = context.scene.ore_render - check_status(ore) - - if bpy.passwordCorrect == False: - row = layout.row() - row.label(text="Email or password missing/incorrect", icon='ERROR') - col = layout.column() - col.prop(ore, 'username', icon=bpy.statusMessage['username']) - col.prop(ore, 'password', icon=bpy.statusMessage['password']) - layout.operator('ore.login') - else: - layout.label(text='Successfully logged in as:', icon='INFO') - layout.label(text=bpy.rffi_user) - layout.operator('ore.change_user') - - layout.label(text='Message from Renderfarm.fi', icon='INFO') - layout.label(text=bpy.rffi_motd) - if bpy.rffi_accepting: - layout.label(text='Accepting sessions', icon='FILE_TICK') - else: - layout.label(text='Not accepting sessions', icon='ERROR') - layout.operator('ore.check_status') - -class SESSIONS_PT_RenderfarmFi(RenderButtonsPanel, bpy.types.Panel): - bl_label = 'My sessions' - COMPAT_ENGINES = set(['RENDERFARMFI_RENDER']) - - @classmethod - def poll(cls, context): - rd = context.scene.render - return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - ore = context.scene.ore_render - if (bpy.passwordCorrect == True and bpy.loginInserted == True): - layout = self.layout - - layout.template_list("UI_UL_list", "rederfarmfi_render", ore, 'all_sessions', ore, 'selected_session', rows=5) - layout.operator('ore.cancel_session') - if (bpy.cancelError == True): - layout.label("This session cannot be cancelled") - errorTime = time.time() - bpy.errorStartTime - if (errorTime > 4): - bpy.cancelError = False - bpy.errorStartTime = -1 - layout.operator('ore.refresh_session_list') - else: - layout = self.layout - layout.label(text="You must login first") - -class RENDER_PT_RenderfarmFi(RenderButtonsPanel, bpy.types.Panel): - bl_label = "Settings" - COMPAT_ENGINES = set(['RENDERFARMFI_RENDER']) - - @classmethod - def poll(cls, context): - rd = context.scene.render - return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - sce = context.scene - ore = sce.ore_render - - if not bpy.rffi_accepting: - layout.label(text="Renderfarm.fi is currently not accepting sessions.") - return - - if (bpy.passwordCorrect == False or bpy.loginInserted == False): - layout.label(text='You must login first') - else: - layout.prop(ore, 'title', icon=bpy.statusMessage['title']) - layout.label(text="Example: Blue Skies project, scene 8") - layout.row() - layout.label(text="The description *MUST* mention some project") - layout.label(text="The project can be a film, commercial work, portfolio or something similar") - layout.label(text="We render only animation projects. Test renders are rejected.") - # layout.prop(ore, 'shortdesc', icon=bpy.statusMessage['shortdesc']) - layout.prop(ore, 'longdesc', icon=bpy.statusMessage['longdesc']) - layout.label(text="Example: In this shot the main hero is running across a flowery field towards the castle.") - layout.prop(ore, 'tags', icon=bpy.statusMessage['tags']) - layout.label(text="Example: blue skies hero castle flowers grass particles") - layout.prop(ore, 'url') - layout.label(text="Example: www.sintel.org") - - #layout.label(text="Please verify your settings", icon='MODIFIER') - row = layout.row() - row = layout.row() - #row.operator('ore.copy_settings') - #row = layout.row() - - layout.label(text="Rendering engine") - row = layout.row() - if (ore.engine == 'blender'): - row.operator('ore.use_blender_render', icon='FILE_TICK') - row.operator('ore.use_cycles_render') - elif (ore.engine == 'cycles' ): - row.operator('ore.use_blender_render') - row.operator('ore.use_cycles_render', icon='FILE_TICK') - else: - row.operator('ore.use_blender_render', icon='FILE_TICK') - row.operator('ore.use_cycles_render') - - row = layout.row() - - layout.separator() - row = layout.row() - row.prop(ore, 'resox') - row.prop(ore, 'resoy') - row = layout.row() - row.prop(ore, 'start') - row.prop(ore, 'end') - row = layout.row() - row.prop(ore, 'fps') - row = layout.row() - if (ore.engine == 'cycles'): - row.prop(ore, 'samples') - row.prop(ore, 'subsamples') - row = layout.row() - row.prop(ore, 'memusage') - #row.prop(ore, 'parts') - layout.separator() - row = layout.row() - - layout.label(text="Licenses", icon='FILE_REFRESH') - row = layout.row() - row.prop(ore, 'inlicense') - row = layout.row() - row.prop(ore, 'outlicense') - - check_status(ore) - if (len(bpy.errors) > 0): - bpy.ready = False - else: - bpy.ready = True - -class UPLOAD_PT_RenderfarmFi(RenderButtonsPanel, bpy.types.Panel): - bl_label = "Upload to www.renderfarm.fi" - COMPAT_ENGINES = set(['RENDERFARMFI_RENDER']) - - @classmethod - def poll(cls, context): - rd = context.scene.render - return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - if not bpy.rffi_accepting: - layout.label(text="Renderfarm.fi is currently not accepting sessions.") - return - - if (bpy.passwordCorrect == False or bpy.loginInserted == False): - layout.label(text="You must login first") - else: - if (bpy.ready): - layout.label(text="Policies", icon='LAMP') - layout.label(text="- The animation must be at least 20 frames long") - layout.label(text="- No still renders") - layout.label(text="- No Python scripts") - layout.label(text="- Memory usage max 4GB") - layout.label(text="- If your render takes more than an hour / frame:") - layout.label(text=" * No filter type composite nodes (blur, glare etc.)") - layout.label(text=" * No SSS") - layout.label(text=" * No Motion Blur") - - layout.separator() - - row = layout.row() - if (bpy.uploadInProgress == True): - layout.label(text="------------------------") - layout.label(text="- Attempting upload... -") - layout.label(text="------------------------") - if (bpy.file_format_warning == True): - layout.label(text="Your output format is HDR", icon='ERROR') - layout.label(text="Right now we don't support this file format") - layout.label(text="File format will be changed to PNG") - if (bpy.texturePackError): - layout.label(text="There was an error in packing external textures", icon='ERROR') - layout.label(text="Make sure that all your textures exist on your computer") - layout.label(text="The render will still work, but won't have the missing textures") - layout.label(text="You may want to cancel your render above in \"My sessions\"") - if (bpy.linkedFileError): - layout.label(text="There was an error in appending linked .blend files", icon='ERROR') - layout.label(text="Your render might not have all the external content") - layout.label(text="You may want to cancel your render above in \"My sessions\"") - if (bpy.particleBakeWarning): - layout.label(text="You have a particle simulation", icon='ERROR') - layout.label(text="All Emitter type particles must be baked") - if (bpy.childParticleWarning): - layout.label(text="Child particle mode changed!", icon='ERROR') - layout.label(text="Renderfarm.fi requires that you use 'Interpolated'") - if (bpy.simulationWarning): - layout.label(text="There is a simulation!", icon='ERROR') - layout.label(text="- Fluid simulations aren't supported") - layout.label(text="- Collision simulations must be baked") - row = layout.row() - row.operator('ore.upload', icon='FILE_TICK') - if (bpy.infoError == True): - layout.label("You must fill in the scene info first", icon='ERROR') - errorTime = time.time() - bpy.errorStartTime - if (errorTime > 4): - bpy.infoError = False - bpy.errorStartTime = -1 - layout.label(text="Warning:", icon='LAMP') - layout.label(text="Blender may seem frozen during the upload!") - row.operator('ore.reset', icon='FILE_REFRESH') - else: - layout.label(text="Fill the scene information first") diff --git a/render_renderfarmfi/prepare.py b/render_renderfarmfi/prepare.py deleted file mode 100644 index 67770635..00000000 --- a/render_renderfarmfi/prepare.py +++ /dev/null @@ -1,189 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import bpy -import os - -def hasSSSMaterial(): - for m in bpy.data.materials: - if m.subsurface_scattering.use: - return True - return False - -def tuneParticles(): - for p in bpy.data.particles: - if (p.type == 'EMITTER'): - bpy.particleBakeWarning = True - if (p.type == 'HAIR'): - if (p.child_type == 'SIMPLE'): - p.child_type = 'INTERPOLATED' - bpy.childParticleWarning = True - -def hasParticleSystem(): - if (len(bpy.data.particles) > 0): - print("Found particle system") - return True - return False - -def hasSimulation(t): - for o in bpy.data.objects: - for m in o.modifiers: - if isinstance(m, t): - print("Found simulation: " + str(t)) - return True - return False - -def hasFluidSimulation(): - return hasSimulation(bpy.types.FluidSimulationModifier) - -def hasSmokeSimulation(): - return hasSimulation(bpy.types.SmokeModifier) - -def hasClothSimulation(): - return hasSimulation(bpy.types.ClothModifier) - -def hasCollisionSimulation(): - return hasSimulation(bpy.types.CollisionModifier) - -def hasSoftbodySimulation(): - return hasSimulation(bpy.types.SoftBodyModifier) - -def hasUnsupportedSimulation(): - return hasSoftbodySimulation() or hasCollisionSimulation() or hasClothSimulation() or hasSmokeSimulation() or hasFluidSimulation() - -def isFilterNode(node): - t = type(node) - return t==bpy.types.CompositorNodeBlur or t==bpy.types.CompositorNodeDBlur - -def changeSettings(): - - sce = bpy.context.scene - rd = sce.render - ore = sce.ore_render - - # Necessary settings for BURP - rd.resolution_x = ore.resox - rd.resolution_y = ore.resoy - sce.frame_start = ore.start - sce.frame_end = ore.end - rd.fps = ore.fps - - bpy.file_format_warning = False - bpy.simulationWarning = False - bpy.texturePackError = False - bpy.particleBakeWarning = False - bpy.childParticleWarning = False - - if (rd.image_settings.file_format == 'HDR'): - rd.image_settings.file_format = 'PNG' - bpy.file_format_warning = True - - # Convert between Blender's image format and BURP's formats - if (rd.image_settings.file_format == 'PNG'): - ore.file_format = 'PNG_FORMAT' - elif (rd.image_settings.file_format == 'OPEN_EXR'): - ore.file_format = 'EXR_FORMAT' - elif (rd.image_settings.file_format == 'OPEN_EXR_MULTILAYER'): - ore.file_format = 'EXR_MULTILAYER_FORMAT' - elif (rd.image_settings.file_format == 'HDR'): - ore.file_format = 'PNG_FORMAT' - else: - ore.file_format = 'PNG_FORMAT' - - if (ore.engine == 'cycles'): - bpy.context.scene.cycles.samples = ore.samples - - if (ore.subsamples <= 0): - ore.subsamples = 1 - - if (ore.samples / ore.subsamples < 100.0): - ore.subsamples = float(ore.samples) / 100.0 - - # Multipart support doesn' work if SSS is used - if ((rd.use_sss == True and hasSSSMaterial()) and ore.parts > 1): - ore.parts = 1; - - if (hasParticleSystem()): - tuneParticles() - else: - bpy.particleBakeWarning = False - bpy.childParticleWarning = False - - if (hasUnsupportedSimulation()): - bpy.simulationWarning = True - else: - bpy.simulationWarning = False - -def _prepare_scene(): - changeSettings() - - print("Packing external textures...") - try: - bpy.ops.file.pack_all() - bpy.texturePackError = False - except Exception as e: - bpy.texturePackError = True - print(e) - - linkedData = bpy.utils.blend_paths() - if (len(linkedData) > 0): - print("Appending linked .blend files...") - try: - bpy.ops.object.make_local(type='ALL') - bpy.linkedFileError = False - except Exception as e: - bpy.linkedFileError = True - print(e) - else: - print("No external .blends used, skipping...") - - # Save with a different name - print("Saving into a new file...") - try: - bpy.originalFileName = bpy.data.filepath - except: - bpy.originalFileName = 'untitled.blend' - print("Original path is " + bpy.originalFileName) - try: - # If the filename is empty, we'll make one from the path of the user's resource folder - if (len(bpy.originalFileName) == 0): - print("No existing file path found, saving to autosave directory") - savePath = bpy.utils.user_resource("AUTOSAVE") - try: - os.mkdir(savePath) - except Exception as ex: - print(ex) - try: - savePath = savePath + "_renderfarm" - except Exception as ex: - print(ex) - try: - bpy.ops.wm.save_mainfile(filepath=savePath) - except Exception as ex: - print(ex) - else: - print("Saving to current .blend directory") - savePath = bpy.originalFileName - savePath = savePath + "_renderfarm.blend" - bpy.ops.wm.save_mainfile(filepath=savePath) - except Exception as e: - print(e) - - print(".blend prepared") - - diff --git a/render_renderfarmfi/rpc.py b/render_renderfarmfi/rpc.py deleted file mode 100644 index bb5d6a45..00000000 --- a/render_renderfarmfi/rpc.py +++ /dev/null @@ -1,198 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import xmlrpc.client -import imp -import time -import bpy - -from .exceptions import LoginFailedException, SessionCancelFailedException, \ - GetSessionsFailedException -from .utils import _read_credentials, _xmlsessions_to_oresessions, \ - update_complete_session_list - -def _is_dev(): - is_dev = False - pwfile = bpy.utils.user_resource('CONFIG', 'rffi', True) - pwmod = None - try: - pwmod = imp.find_module('rffi_dev',[pwfile]) - try: - user_creds = imp.load_module('rffi_dev', pwmod[0], pwmod[1], pwmod[2]) - if 'dev' in dir(user_creds) and user_creds.dev: - is_dev = True - except ImportError: - is_dev = False - finally: - if pwmod and pwmod[0]: pwmod[0].close() - except ImportError: - is_dev = False - finally: - if pwmod and pwmod[0]: pwmod[0].close() - - return is_dev - -def _be_verbose(): - be_verbose = False - pwfile = bpy.utils.user_resource('CONFIG', 'rffi', True) - pwmod = None - try: - pwmod = imp.find_module('rffi_dev',[pwfile]) - try: - user_creds = imp.load_module('rffi_dev', pwmod[0], pwmod[1], pwmod[2]) - if 'verbose' in dir(user_creds) and user_creds.verbose: - be_verbose = True - except ImportError: - be_verbose = False - finally: - if pwmod and pwmod[0]: pwmod[0].close() - except ImportError: - be_verbose = False - finally: - if pwmod and pwmod[0]: pwmod[0].close() - - return be_verbose - -RFFI_DEV = _is_dev() -RFFI_VERBOSE = _be_verbose() - -if RFFI_DEV: - print("DEVELOPER MODE") - rffi_xmlrpc_secure = r'http://renderfarm.server/burp/xmlrpc' - rffi_xmlrpc = r'http://renderfarm.server/burp/xmlrpc' - rffi_xmlrpc_upload = 'renderfarm.server' -else: - rffi_xmlrpc_secure = r'http://xmlrpc.renderfarm.fi/burp/xmlrpc' - rffi_xmlrpc = r'http://xmlrpc.renderfarm.fi/burp/xmlrpc' - rffi_xmlrpc_upload = 'xmlrpc.renderfarm.fi' - - -def _get_proxy(): - proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc, verbose=RFFI_VERBOSE) - return proxy - -def _get_secure_proxy(): - proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc_secure, verbose=RFFI_VERBOSE) - return proxy - -def _do_refresh(op, rethrow=False, print_errors=True): - sce = bpy.context.scene - ore = sce.ore_render - - if _read_credentials(): - try: - bpy.ore_sessions = [] - bpy.ore_pending_sessions = [] - bpy.ore_active_sessions = [] - bpy.ore_completed_sessions = [] - bpy.ore_cancelled_sessions = [] - update_complete_session_list(ore) - - res = rffi.login(op, True, print_errors) - userid = res['userID'] - - sessions = rffi.get_sessions(userid, 'accept', 0, 100, 'full') - bpy.ore_sessions = _xmlsessions_to_oresessions(sessions, stage='Pending') - bpy.ore_pending_sessions = bpy.ore_sessions - - sessions = rffi.get_sessions(userid, 'completed', 0, 100, 'full') - bpy.ore_sessions = _xmlsessions_to_oresessions(sessions, stage='Completed') - bpy.ore_completed_sessions = bpy.ore_sessions - - sessions = rffi.get_sessions(userid, 'cancelled', 0, 100, 'full') - bpy.ore_sessions = _xmlsessions_to_oresessions(sessions, stage='Cancelled') - bpy.ore_cancelled_sessions = bpy.ore_sessions - - sessions = rffi.get_sessions(userid, 'render', 0, 100, 'full') - bpy.ore_sessions = _xmlsessions_to_oresessions(sessions, stage='Rendering') - bpy.ore_active_sessions = bpy.ore_sessions - - update_complete_session_list(ore) - - return 0 - except LoginFailedException as lfe: - if print_errors: print("_do_refresh login failed", lfe) - if rethrow: - raise lfe - return 1 - else: - return 1 - - -class RffiRpc(object): - def __init__(self): - self.proxy = _get_proxy() - self.sproxy = _get_secure_proxy() - self.res = None - - def login(self, op, rethrow=False, print_errors=True): - self.res = None - - if bpy.rffi_user=='': - raise LoginFailedException("No email address given") - - if bpy.rffi_hash=='': - raise LoginFailedException("No password given") - - try: - self.res = self.sproxy.auth.getSessionKey(bpy.rffi_user, bpy.rffi_hash) - except xmlrpc.client.Error as v: - if op: op.report({'WARNING'}, "Error at login : " + str(type(v)) + " -> " + str(v.faultCode) + ": " + v.faultString) - if print_errors: print("Error at login: ",v) - if rethrow: - vstr = str(v) - if "Failed to invoke method getSessionKey" in vstr: - raise LoginFailedException('User '+bpy.rffi_user+' doesn\'t exist') - raise LoginFailedException(v.faultString) - return None - except Exception as v: - if op: op.report({'WARNING'}, "Non XMLRPC Error at login: " + str(v)) - if print_errors: print(v) - if rethrow: - raise LoginFailedException(str(v)) - return None - return self.res - - def get_sessions(self, user, queue, start, end, level): - try: - sessions = self.proxy.session.getSessions(user, queue, start, end, level) - except xmlrpc.client.Error as v: - raise GetSessionsFailedException(str(v)) - return sessions - - def cancel_session(self, op, session): - res = self.login(op) - if res: - try: - key = res['key'] - userid = res['userId'] - res = self.proxy.session.cancelSession(userid, key, session.id) - _do_refresh(op, True) - op.report({'INFO'}, 'Session ' + session.title + ' with id ' + str(session.id) + ' cancelled') - except xmlrpc.client.Error as v: - op.report({'ERROR'}, 'Could not cancel session ' + session.title + ' with id ' + str(session.id)) - bpy.cancelError = True - bpy.errorStartTime = time.time() - raise SessionCancelFailedException(str(v)) - - def check_status(self): - res = self.proxy.service.motd() - bpy.rffi_accepting = res['accepting'] - bpy.rffi_motd = res['motd'] - -rffi = RffiRpc() diff --git a/render_renderfarmfi/upload.py b/render_renderfarmfi/upload.py deleted file mode 100644 index 5bf28bed..00000000 --- a/render_renderfarmfi/upload.py +++ /dev/null @@ -1,193 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import xmlrpc.client -import http.client -import hashlib -from os.path import isabs, isfile -import time - -import bpy - -from .utils import _read_credentials -from .rpc import rffi, _do_refresh, rffi_xmlrpc_upload, rffi_xmlrpc, RFFI_VERBOSE - -def _random_string(length): - import string - import random - return ''.join(random.choice(string.ascii_letters) for ii in range(length + 1)) - -def _encode_multipart_data(data, files): - boundary = _random_string(30) - - def get_content_type(filename): - return 'application/octet-stream' # default this - - def encode_field(field_name): - return ('--' + boundary, - 'Content-Disposition: form-data; name="%s"' % field_name, - '', str(data[field_name])) - - def encode_file(field_name): - filename = files [field_name] - fcontent = None - print('encoding', field_name) - try: - fcontent = str(open(filename, 'rb').read(), encoding='iso-8859-1') - except Exception as e: - print('Trouble in paradise', e) - return ('--' + boundary, - 'Content-Disposition: form-data; name="%s"; filename="%s"' % (field_name, filename), - 'Content-Type: %s' % get_content_type(filename), - '', fcontent) - - lines = [] - for name in data: - lines.extend(encode_field(name)) - for name in files: - lines.extend(encode_file(name)) - lines.extend(('--%s--' % boundary, '')) - print("joining lines into body") - body = '\r\n'.join(lines) - - headers = {'content-type': 'multipart/form-data; boundary=' + boundary, - 'content-length': str(len(body))} - - print("headers and body ready") - - return body, headers - -def _send_post(data, files): - print("Forming connection for post") - connection = http.client.HTTPConnection(rffi_xmlrpc_upload) - print("Requesting") - connection.request('POST', '/burp/storage', *_encode_multipart_data(data, files)) # was /file - print("Getting response") - response = connection.getresponse() - print("Reading response") - res = response.read() - return res - -def _md5_for_file(filepath): - md5hash = hashlib.md5() - blocksize = 0x10000 - f = open(filepath, "rb") - while True: - data = f.read(blocksize) - if not data: - break - md5hash.update(data) - return md5hash.hexdigest() - -def _upload_file(key, userid, sessionid, path): - print("Asserting absolute path") - assert isabs(path) - print("Asserting path is a file") - assert isfile(path) - data = { - 'userId': str(userid), - 'sessionKey': key, - 'sessionId': sessionid, - 'md5sum': _md5_for_file(path) - } - files = { - 'blenderfile': path - } - r = _send_post(data, files) - - return r - -def _run_upload(key, userid, sessionid, path): - print("Starting upload"); - r = _upload_file(key, userid, sessionid, path) - print("Upload finished") - o = xmlrpc.client.loads(r) - print("Loaded xmlrpc response") - return o[0][0] - -def _ore_upload(op, context): - sce = context.scene - ore = sce.ore_render - - if not bpy.ready: - op.report({'ERROR'}, 'Your user or scene information is not complete') - bpy.infoError = True - bpy.errorStartTime = time.time() - bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' - return {'CANCELLED'} - try: - _read_credentials() - res = rffi.login(op, True) - key = res['key'] - userid = res['userId'] - print("Creating server proxy") - proxy = xmlrpc.client.ServerProxy(rffi_xmlrpc, verbose=RFFI_VERBOSE) - proxy._ServerProxy__transport.user_agent = 'Renderfarm.fi Uploader/%s' % (bpy.CURRENT_VERSION) - print("Creating a new session") - res = proxy.session.createSession(userid, key) # This may use an existing, non-rendered session. Prevents spamming in case the upload fails for some reason - sessionid = res['sessionId'] - key = res['key'] - print("Session id is " + str(sessionid)) - res = _run_upload(key, userid, sessionid, bpy.data.filepath) - print("Getting fileid from xmlrpc response data") - fileid = int(res['fileId']) - print("Sending session details for session " + str(sessionid) + " with fileid " + str(fileid)) - res = proxy.session.setTitle(userid, res['key'], sessionid, ore.title) - res = proxy.session.setLongDescription(userid, res['key'], sessionid, ore.longdesc) - res = proxy.session.setShortDescription(userid, res['key'], sessionid, ore.shortdesc) - if len(ore.url)>0: - res = proxy.session.setExternalURLs(userid, res['key'], sessionid, ore.url) - res = proxy.session.setStartFrame(userid, res['key'], sessionid, ore.start) - res = proxy.session.setEndFrame(userid, res['key'], sessionid, ore.end) - res = proxy.session.setSplit(userid, res['key'], sessionid, ore.parts) - res = proxy.session.setMemoryLimit(userid, res['key'], sessionid, ore.memusage) - res = proxy.session.setXSize(userid, res['key'], sessionid, ore.resox) - res = proxy.session.setYSize(userid, res['key'], sessionid, ore.resoy) - res = proxy.session.setFrameRate(userid, res['key'], sessionid, ore.fps) - res = proxy.session.setFrameFormat(userid, res['key'], sessionid, ore.file_format) - res = proxy.session.setRenderer(userid, res['key'], sessionid, ore.engine) - res = proxy.session.setSamples(userid, res['key'], sessionid, ore.samples) - res = proxy.session.setSubSamples(userid, res['key'], sessionid, ore.subsamples) - if (ore.engine == 'cycles'): - res = proxy.session.setReplication(userid, res['key'], sessionid, 1) - if ore.subsamples > 1: - res = proxy.session.setStitcher(userid, res['key'], sessionid, 'AVERAGE') - else: - res = proxy.session.setReplication(userid, res['key'], sessionid, 3) - res = proxy.session.setOutputLicense(userid, res['key'], sessionid, int(ore.outlicense)) - res = proxy.session.setInputLicense(userid, res['key'], sessionid, int(ore.inlicense)) - print("Setting primary input file") - res = proxy.session.setPrimaryInputFile(userid, res['key'], sessionid, fileid) - print("Submitting session") - res = proxy.session.submit(userid, res['key'], sessionid) - print("Session submitted") - op.report({'INFO'}, 'Submission sent to Renderfarm.fi') - except xmlrpc.client.Error as v: - bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' - print('ERROR:', v) - op.report({'ERROR'}, 'An XMLRPC error occurred while sending submission to Renderfarm.fi') - except Exception as e: - bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' - print('Unhandled error:', e) - op.report({'ERROR'}, 'A generic error occurred while sending submission to Renderfarm.fi') - - bpy.context.scene.render.engine = 'RENDERFARMFI_RENDER' - _do_refresh(op) - return {'FINISHED'} - - diff --git a/render_renderfarmfi/utils.py b/render_renderfarmfi/utils.py deleted file mode 100644 index 8afcfd78..00000000 --- a/render_renderfarmfi/utils.py +++ /dev/null @@ -1,137 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -import imp - -from os.path import join - -import bpy - -from .ore_session import OreSession - -def _write_credentials(hash, user): - with open(join(bpy.utils.user_resource('CONFIG', 'rffi', True), 'rffi_credentials.py'), 'w') as pwfile: - pwfile.write('hash=\''+hash+'\'\n') - pwfile.write('user=\''+user+'\'') - - -def _read_credentials(): - bpy.rffi_creds_found = False - bpy.rffi_user = '' - bpy.rffi_hash = '' - - pwfile = bpy.utils.user_resource('CONFIG', 'rffi', True) - try: - pwmod = imp.find_module('rffi_credentials',[pwfile]) - except ImportError: - _write_credentials('', '') - pwmod = imp.find_module('rffi_credentials',[pwfile]) - try: - user_creds = imp.load_module('rffi_credentials', pwmod[0], pwmod[1], pwmod[2]) - bpy.rffi_user = user_creds.user - bpy.rffi_hash = user_creds.hash - bpy.rffi_creds_found = True - except ImportError: - # doesn't exist yet, write template - _write_credentials('', '') - pwfile = bpy.utils.user_resource('CONFIG', 'rffi', True) - pwmod = imp.find_module('rffi_credentials',[pwfile]) - try: - user_creds = imp.load_module('rffi_credentials', pwmod[0], pwmod[1], pwmod[2]) - bpy.rffi_user = user_creds.user - bpy.rffi_hash = user_creds.hash - bpy.rffi_creds_found = True - except Exception as e2: - print("Couldn't write rffi_credentials.py", e2) - finally: - if pwmod and pwmod[0]: pwmod[0].close() - - return bpy.rffi_creds_found - - -def _xmlsessions_to_oresessions(sessions, stage=None): - output = [] - for session in sessions: - s = session['title'] - if stage: - s = s + ' (' + stage + ')' - sinfo = OreSession(session['sessionId'], s) - if stage in {'Rendering', 'Completed', 'Active'}: - sinfo.frames = session['framesRendered'] - sinfo.startframe = session['startFrame'] - sinfo.endframe = session['endFrame'] - output.append(sinfo) - return output - - -def update_session_list(session_list, ore): - while(len(session_list) > 0): - session_list.remove(0) - - for s in bpy.ore_active_session_queue: - session_list.add() - session = session_list[-1] - session.name = s.title + ' [' + str(s.percentageComplete()) + '% complete]' - -def update_complete_session_list(ore): - bpy.ore_active_session_queue = bpy.ore_cancelled_sessions - update_session_list(ore.rejected_sessions, ore) - bpy.ore_active_session_queue = bpy.ore_active_sessions - update_session_list(ore.active_sessions, ore) - bpy.ore_active_session_queue = bpy.ore_pending_sessions - update_session_list(ore.pending_sessions, ore) - bpy.ore_active_session_queue = bpy.ore_completed_sessions - update_session_list(ore.completed_sessions, ore) - - bpy.ore_complete_session_queue = [] - bpy.ore_complete_session_queue.extend(bpy.ore_pending_sessions) - bpy.ore_complete_session_queue.extend(bpy.ore_active_sessions) - bpy.ore_complete_session_queue.extend(bpy.ore_completed_sessions) - bpy.ore_complete_session_queue.extend(bpy.ore_cancelled_sessions) - - bpy.ore_active_session_queue = bpy.ore_complete_session_queue - update_session_list(ore.all_sessions, ore) - -def check_status(ore): - bpy.errors = [] - - if bpy.rffi_creds_found == False and bpy.rffi_hash == '': - bpy.errors.append('missing_creds') - - if '' in {ore.title, ore.longdesc, ore.shortdesc}: - bpy.errors.append('missing_desc') - bpy.infoError = True - - set_status('username', bpy.rffi_hash=='' and ore.username=='') - set_status('password', bpy.rffi_hash=='' and ore.password=='') - - set_status('title', ore.title=='') - set_status('longdesc', ore.longdesc=='') - set_status('shortdesc', ore.shortdesc=='') - - -def set_status(property, status): - if status: - bpy.statusMessage[property] = 'ERROR' - else: - bpy.statusMessage[property] = 'TRIA_RIGHT' - -def show_status(layoutform, property, message): - if bpy.statusMessage[property] == 'ERROR': - layoutform.label(text='', icon='ERROR') - |