Remove plugin for now-dysfunctional Renderfarm.fi. R.I.P.
This commit is contained in:
parent
0015dd2308
commit
9a3a63d01d
|
@ -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
|
|
@ -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
|
|
@ -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'}
|
|
@ -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
|
|
@ -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")
|
|
@ -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")
|
||||
|
||||
|
|
@ -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()
|
|
@ -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'}
|
||||
|
||||
|
|
@ -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')
|
||||
|
Loading…
Reference in New Issue