def logout(self): log.info("Logging out...") try: self._logout() except MasterServerError, e: log.error(e) return False
def disconnect(self): log.info("Disconnecting...") try: self._chat_disconnect() except ChatServerError, e: log.error(e) return False
def publish(self): log.info("Publishing movie for %s to snapshot" % self.shot) # Get paths for the playblast from MSSQL log.info( "Getting playblast paths") self.local_file = "%s/%s" % (self.local_path, self.movie_file) self.server_file = "%s/%s" % (self.shotfile.playblast_server_path, self.movie_file) # Copy the movie file to the database, and log it with MSSQL log.info( "Saving movie for shot %s to snapshot and network file storage" % self.shot) try: from_file = "%s/%s" % (self.local_path, self.movie_file) to_file = "%s/%s" % (self.server_path, self.movie_file) log.info("Copying %s > %s" % (from_file, to_file)) shutil.copy(from_file, to_file) log.info( "Copied %s > %s" % (from_file, to_file)) from_file = "%s/%s" % (self.local_path, self.movie_file) to_file = "%s/%s" % (self.server_path_version, self.movie_file) log.info("Copying %s > %s" % (from_file, to_file)) shutil.copy(from_file, to_file) log.info( "Copied %s > %s" % (from_file, to_file)) except: log.error( "Could not copy playblast for shot %s to server paths %s and/or %s" % (self.shot, self.server_path, self.server_path_version)) else: # Store info in MSSQL sql.create_playblast_version(self.shot.show.code, self.shot.sequence.code, self.shot.code, self.shot.process, 1)
def module_start(): global db_cursor, nickserv try: db_cursor=Database.conn.cursor() nickserv=Pseudoclient.create("NickServ", "NickServ", "nickserv", config.get("Services/DefaultHostname"), "Nickname registration and protection service") if(nickserv is None): raise Exception("A pseudoclient with this service name already exists (NickServ)") if(nickserv is False): raise Exception("A pseudoclient with this nick already exists (NickServ)") try: db_cursor.execute("describe `ff_nickserv_core`") except Exception: #the table isn't there, now try to create it db_cursor.execute(""" CREATE TABLE `ff_nickserv_core` ( `id` BIGINT( 1 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `nick` VARCHAR( 128 ) NOT NULL , `password` VARCHAR( 256 ) NOT NULL , `email` VARCHAR( 256 ) NULL , `time_registered` BIGINT( 1 ) NOT NULL , `time_last_seen` BIGINT( 1 ) NOT NULL , `email_confirmed` BOOLEAN NOT NULL , `activated` BOOLEAN NOT NULL , `disabled` BOOLEAN NOT NULL , `group` BIGINT( 1 ) NULL DEFAULT NULL , `confirmation_code` VARCHAR( 64 ) NULL DEFAULT NULL , INDEX ( `time_registered` , `time_last_seen` , `email_confirmed` , `activated` , `disabled` , `group` , `confirmation_code` ) ) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci; """) except Exception as e: log.error("Can't start ff_NickServ: %s", str(e)) return False nickserv.help="""\x02NickServ\x02 - Nickname registration and protection service. \x02NickServ\x02 allows nicknames to be registered to a particular user to prevent others from using them. Abuse of the service for stealing others' nicknames is not permitted and may result in a network ban. The available commands are listed below, if you require help with any of them type \x02/msg NickServ help \x1fcommand\x1f\x02.""" nickserv.addCommand(PseudoclientCommand("register", handle_cmd_register, "Register your current nickname", """Syntax: \x02/msg NickServ register \x1fpassword\x1f [\x1femail\x1f]\x02 The \x02register\x02 command registers your current nickname with \x02NickServ\x02. To register a nickname, the nickname must not already be registered, and it must be a nickname that is permitted by the IRCD. A valid email address may be required on some networks in order to activate the nickname registration.""" )) nickserv.addCommand(PseudoclientCommand("identify", handle_cmd_identify, "Identify yourself using your password", """Syntax: \x02/msg NickServ identify \x1fpassword\x1f\x02 The \x02identify\x02 command identifies you as owning your nick, and allows you to access additional features of NickServ.""" )) nickserv.addCommand(PseudoclientCommand("unidentify", handle_cmd_unidentify, "Remove your status as an identified user", """Syntax: \x02/msg NickServ unidentify\x02 The \x02unidentify\x02 command removes your identified status if you have previously identified.""" )) nickserv.addCommand(PseudoclientCommand("group", handle_cmd_group, "Group your current nick with another nick", """Syntax: \x02/msg NickServ group [\x1fprimarynick password\x1f]\x02 The \x02group\x02 command allows you to group your current nick with your primary nick, allowing you to use it for identification and to prevent others from using it. If you have previously identified you do not have to supply any parameters, however if you are not identified you will have to supply your primary nickname (or any nickname grouped with that nickname) and your password.""" )) nickserv.addCommand(PseudoclientCommand("glist", handle_cmd_glist, "List the nicknames that are in your group", """Syntax: \x02/msg NickServ glist\x02 The \x02glist\x02 command lists all of the nicknames currently in your group.""" )) return True
def login(self, username, password): log.info("Logging in..") if len(password) != 32: password = md5(password).hexdigest() try: self._login(username, password) except MasterServerError, e: log.error(e) return False
def create_dirs(self, dir_path): if not os.path.exists(dir_path): try: os.makedirs(dir_path) except: log.error("Can't create playblast path %s for shot %s.%s" % (dir_path, self.sequence, self.shot)) return False return True
def nick_is_registered(nick): global db_cursor try: db_cursor.execute("select count(`nick`) from `ff_nickserv_core` where `nick` like %s", (nick)) existing_nick_count=db_cursor.fetchone()[0] if(existing_nick_count>0): return True return False except Exception as e: log.error("%s", str(e)) return True
def connect(self): """ Wrapper function, handles connecting only. Used to re-connect. """ try: self._chat_connect() except ChatServerError, e: log.error(e) return False
def authenticate(nick, password, real_password=None): global db_cursor if(real_password is None): try: db_cursor.execute("select `password` from `ff_nickserv_core` where `nick` like %s", (nick)) real_password=db_cursor.fetchone()[0] except Exception as e: log.error("%s", str(e)) return None if(hash_password(nick, password)==real_password): return True return False
def logout(self): log.info("Disconnecting...") if not self.is_connected: self.logged_in = False return try: self._chat_disconnect() except ChatServerError, e: log.error(e)
def login(self): """ Wrapper function for convience and logic, handles both logging in and connecting. """ log.info("Logging in...") try: self._login(config.username, config.password) except MasterServerError, e: log.error(e) return False
def handle_cmd_register(source, command, c_text): global db_cursor, nickserv c_params=c_text.split() if(len(c_params)==0): nickserv.sendMsg(source, "The \x02register\x02 command required at least one argument.") return if(len(c_params)==1 and config.get("Services/ff_NickServ/Registration/RequireEmail")): nickserv.sendMsg(source, "A valid email address is required to register your nickname.") return try: #db_cursor.execute("select count(`nick`) from `ff_nickserv_core` where `nick` like %s", (source)) #existing_nick_count=db_cursor.fetchone()[0] #if(existing_nick_count>0): # nickserv.sendMsg(source, "The nick \x02%s\x02 is already registered.", source) # return if(nick_is_registered(source)): #will return true if an error is encountered to prevent registration of the same nick twice nickserv.sendMsg(source, "The nick \x02%s\x02 is already registered.", source) return conf_code=hashlib.md5(str(random.random())+str(time.time())).hexdigest() db_cursor.execute("""insert into `ff_nickserv_core` (`nick`,`password`,`email`,`time_registered`,`time_last_seen`,`email_confirmed`,`activated`,`disabled`,`group`,`confirmation_code`) values(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", ( source, hash_password(source, c_params[0]), c_params[1] if len(c_params)>1 else None, long(time.time()), long(time.time()), 0 if config.get("Services/ff_NickServ/Registration/RequireEmail Confirmation") else 1, 0 if config.get("Services/ff_NickServ/Registration/RequireOperActivation") else 1, 0, None, conf_code )) if(config.get("Services/ff_NickServ/Registration/RequireEmail Confirmation")): #todo: send email #if email fails, delete the nick and display an error nickserv.sendMsg(source, "An activation email has been sent to \x02%s\x02 with a confirmation code. When you have recieved the email, you will have to enter the command \x02/msg NickServ confirm \x1fconfirmationcode\x1f\x02. Until you do so, you will not be able to identify with this nickname.", c_params[1]) if(config.get("Services/ff_NickServ/Registration/RequireOperActivation")): nickserv.sendMsg(source, "You will not be able to identify using this nickname until an IRC operator has activated your account.") nickserv.sendMsg(source, "The nickname \x02%s\x02 has been registered using the password \x02%s\x02 - please memorize your password or keep it in a safe place, as it may be impossible to retrieve it.", source, c_params[0]) log.info("NickServ: Registering new nick and creating group for '%s' (email: %s)", source, c_params[1] if len(c_params)>1 else "none") except Exception as e: nickserv.sendMsg(source, "There was a problem registering your nickname.") log.error("Can't register nick %s: %s", source, str(e)) return False
def main(): db.connect(config.dbhost, config.dbuser, config.dbpass, config.dbname) hon_monitor = HoNStatus() test_count = 1 while True: log.info("Running test #" + str(test_count)) # Reconfigure the monitor. hon_monitor.configure() login_status, login_reason = hon_monitor.login_test() log.info("Login server: %s - %s" % (login_status, login_reason)) chat_status, chat_reason = hon_monitor.chat_test() log.info("Chat Server: %s - %s" % (chat_status, chat_reason)) # MotD data can be checked each test, regardless of the server statuses. try: hon_monitor.motd_parser() except MasterServerError, e: if e.code == 108: log.error('Could not obtain MotD data from the Master server') # Check that all tests returned good, otherwise the test fails and should # be re-attempted in 90 seconds if login_status is "Up" and chat_status is "Up": hon_monitor.logged_in = True timer = 0 while hon_monitor.is_logged_in: timer += 1 if timer >= 300: hon_monitor.disconnect_logout() break else: time.sleep(1) # Client disconnected, cool down for a moment log.debug("Client disconnected, cooling..") time.sleep(2) else: # Start dropping the players online to zero once it's been determined that # the servers are down. if down_count > 5: db.execute("""INSERT INTO players (time, value) VALUES (%s, %s)""", [str(int(time.time())), 0]) time.sleep(90) # Loop increment test_count += 1 # And log back out again hon_monitor.logged_in = False
def handle_cmd_glist(source_s, command, c_text): global db_cursor, nickserv client=Client.findByNick(source_s) if(not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not registered.") return try: db_cursor.execute("select `nick`, `time_registered`, `time_last_seen` from `ff_nickserv_core` where `id`=%s or `group`=%s order by `id` asc", (client.servicestamp, client.servicestamp)) nickserv.sendMsg(source_s, "Nicknames in the group of \x02%s\x02:", source_s) for g_data in db_cursor.fetchall(): nickserv.sendMsg(source_s, "\x02%s\x02 (Registered %s ago, last seen %s ago)", g_data[0], ffservices.formatTimeDiff(g_data[1], time.time(), False), ffservices.formatTimeDiff(g_data[2], time.time(), False)) except Exception as e: log.error("%s", str(e))
def enable(self, plugin, enabled=True): """ Enable/disable plugins. """ if not plugin in self._node_data: log.error('plugin "%s" not recognized.' % plugin) return False for plug, plugin_attrs in self._node_data.iteritems(): if plug == plugin: log.info('setting plugin "%s" enabled: %s' % (plugin, str(enabled))) self._node_data.get(plugin).update(enabled=enabled) return True return False
def close_socket(s): if not isinstance(s, socket.socket): log.warn('it is not socket') return try: s.shutdown(socket.SHUT_RDWR) log.trace(0, 'socket close: %d', s.fileno()) return except Exception as exc: log.error(exc, 'socket.shutdown(%d) fail', s.fileno()) try: s.close() return except Exception as exc: log.error(exc, 'socket.close(%d) fail', s.fileno())
def handle_cmd_identify(source_s, command, c_text): global db_cursor, nickserv client=Client.findByNick(source_s) if(client is None): nickserv.sendMsg(source_s, "You do not seem to exist. This is a bug, please report it.") return if(client.hasMode("r")): nickserv.sendMsg(source_s, "You have already identified.") return try: db_cursor.execute("select * from `ff_nickserv_core` where `nick` like %s limit 1", (source_s)) if(db_cursor.rowcount==0): nickserv.sendMsg(source_s, "Nick \x02%s\x02 is not registered.", source_s) return u_id, nick, password, email, time_registered, time_last_seen, email_confirmed, activated, disabled, group, confirmation_code=db_cursor.fetchone() if(len(c_text)==0): nickserv.sendMsg(source_s, "You must supply a password.") return #elif(password==hash_password(source_s, c_text)): elif(authenticate(source_s, c_text, password)): if(not email_confirmed): nickserv.sendMsg(source_s, "You have not confirmed your email address.") return elif(not activated): nickserv.sendMsg(source_s, "Your account has not yet been activated.") return elif(disabled): nickserv.sendMsg(source_s, "Your account has been disabled.") return client.changeModes("+r") groupid=group if group is not None else u_id Network.sendMsg(IRCMessage(":", nickserv.nick, "SVS2MODE", source_s, "+rd", groupid)) client.servicestamp=groupid #using mode +d with svsmode or svs2mode changes the services stamp #in this case we set it to the user's group ID db_cursor.execute("update `ff_nickserv_core` set `time_last_seen`=%s where id=%s limit 1", (time.time(), u_id)) nickserv.sendMsg(source_s, "You are now identified for nick \x02%s\x02.", nick) else: nickserv.sendMsg(source_s, "Invalid password.") return except Exception as e: log.error("Can't identify user %s: %s", source_s, str(e)) nickserv.sendMsg(source_s, "A problem was encountered -- this is likely a bug, please report it.")
def process_events(self, wait_time=20): if wait_time: wait_time = float(wait_time) / 1000 else: wait_time = 0.02 try: r, w, x = select.select(self.r_list, self.w_list, self.x_list, wait_time) except Exception as exc: log.error(exc, 'select() fail') exit(-1) return if not (r or w or x): return closed = {} for s in r: if not self.r_datas.has_key(s): continue ev, c = self.r_datas[s] if not c.socket(): closed[s] = c continue ev.process(self.name) for s in w: if not self.w_datas.has_key(s): continue ev, c = self.w_datas[s] if not c.socket(): closed[s] = c continue ev.process(self.name) for s in closed: c = closed[s] if c.wev.active: self.w_list.remove(s) del self.w_datas[s] if c.rev.active: self.r_list.remove(s) del self.r_datas[s]
def __init__(self, shotfile): self.shotfile = shotfile self.shot = shotfile.shot self.show = shot.sequence.show log.info( "Getting data for playblast for %s.%s" % (self.sequence, self.shot)) self.min_frame = 0 self.max_frame = 0 self.local_pblast_name = "C:/temp/banzai_data/temp_playblast" # Path to RV executables self.rv_path = "C:/Program Files (x86)/Tweak/RV-3.10/bin" if not os.path.exists(self.rv_path): self.rv_path = "C:/Program Files (x86)/Tweak/RV-3.8/bin" if not os.path.exists(self.rv_path): log.error("Can't find the path to RV or RVIO - email [email protected]") self.rv_support_path = os.getenv('RV_SUPPORT_PATH')
def __init__(self, shotfile): self.shotfile = shotfile self.shot = self.shotfile.shot self.sequence = self.shot.sequence self.movie = None self.min_frame = 0 self.max_frame = 0 self.width = self.shotfile.shot.sequence.show.res_playblast_x self.height = self.shotfile.shot.sequence.show.res_playblast_y # Path to RV executables self.rv_path = "C:/Program Files (x86)/Tweak/RV-3.10/bin" if not os.path.exists(self.rv_path): self.rv_path = "C:/Program Files (x86)/Tweak/RV-3.8/bin" if not os.path.exists(self.rv_path): self.rv_path = "C:/Program Files (x86)/Tweak/RV-3.12.19-32/bin" if not os.path.exists(self.rv_path): log.error("Can't find the path to RV or RVIO - contact support")
def module_start(): global db_cursor, statserv try: db_cursor=Database.conn.cursor() statserv=Pseudoclient.create("StatServ", "StatServ", "statserv", config.get("Services/DefaultHostname"), "Network statistics tracker") if(statserv is None): raise Exception("A pseudoclient with this service name already exists (StatServ)") if(statserv is False): raise Exception("A pseudoclient with this nick already exists (StatServ)") try: db_cursor.execute("describe `ff_statserv_lusers`") except Exception: db_cursor.execute("""CREATE TABLE `ff_statserv_lusers` ( `time` BIGINT( 1 ) NOT NULL , `normal_users` BIGINT( 1 ) NOT NULL , `invisible_users` BIGINT( 1 ) NOT NULL , `servers` BIGINT( 1 ) NOT NULL , PRIMARY KEY ( `time` ) , INDEX ( `normal_users` , `invisible_users` , `servers` ) ) ENGINE = MYISAM ;""") db_cursor.execute("""ALTER TABLE `ff_statserv_lusers` ADD `opers` BIGINT( 1 ) NOT NULL , ADD INDEX ( `opers` )""") db_cursor.execute("""ALTER TABLE `ff_statserv_lusers` ADD `channels` BIGINT( 1 ) NOT NULL , ADD INDEX ( `channels` )""") db_cursor.execute("""CREATE TABLE `ff_statserv_channels` ( `time` BIGINT( 1 ) NOT NULL , `channel` VARCHAR( 128 ) NOT NULL , `nick` VARCHAR( 128 ) NOT NULL , `nickserv_groupid` BIGINT( 1 ) NULL DEFAULT NULL , `message_type` VARCHAR( 16 ) NOT NULL , `message` VARCHAR( 2048 ) NOT NULL , PRIMARY KEY ( `time` ) , INDEX ( `nickserv_groupid` ) ) ENGINE = MYISAM ;""") db_cursor.execute("""ALTER TABLE `ff_statserv_channels` CHANGE `time` `time` DOUBLE NOT NULL""") except Exception as e: log.error("Can't start ff_StatServ: %s", str(e)) return False Timer.add(do_lusers_update, 60) #every 60 seconds works out to a little over 500,000 rows per year, which is #pretty acceptible -- stats probably do not need to be kept longer than a few #months, anyway return True
def get_dagnode(self, node_type, **kwargs): """ Return the appropriate dag node type. :param str node_type: dag node type to return. :returns: dag node subclass. :rtype: DagNode """ if node_type not in self._node_data: log.error('plugin type "%s" is not loaded.' % node_type) return dag = self._node_data.get(node_type).get('dagnode') # assign the node metadata file result = dag(_metadata=self._node_data.get(node_type).get( 'metadata', None), **kwargs) return result
def get_widget(self, dagnode, **kwargs): """ Return the appropriate node type widget. Returns the default widget if one is not defined. :param DagNode dagnode: node type. :returns: node widget subclass. :rtype: NodeWidget """ if dagnode.node_type not in self._node_data: log.error('plugin "%s" is not loaded.' % dagnode.node_type) return if 'widget' not in self._node_data.get(dagnode.node_type): log.error('plugin "%s" widget not loaded.' % dagnode.node_type) return widget = self._node_data.get(dagnode.node_type).get('widget') return widget(dagnode)
def handle_cmd_group(source_s, command, c_text): global db_cursor, nickserv params=c_text.split() if(nick_is_registered(source_s)): nickserv.sendmsg(source_s, "Nick \x02%s\x02 is already registered.", source_s) elif(len(params)==1): nickserv.sendMsg(source_s, "You must either supply both a registered nickname and a password, or nothing (if you are already identified).") elif(len(params)>1): if(not nick_is_registered(params[0])): nickserv.sendMsg(source_s, "Nick \x02%s\x02 is not registered.", params[0]) return try: db_cursor.execute("select `id`,`password`,`group` from `ff_nickserv_core` where `nick` like %s limit 1", (params[0])) u_id, password, group=db_cursor.fetchone() except Exception as e: log.error("%s", str(e)) nickserv.sendMsg(source_s, "Your nick cannot be grouped at this time.") return groupid=group if group is not None else u_id if(not authenticate(params[0], params[1], password)): nickserv.sendMsg(source_s, "Incorrect password.") return else: client=Client.findByNick(source_s) #TODO: check if client is none if(not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not identified.") return groupid=client.servicestamp try: db_cursor.execute("""insert into `ff_nickserv_core` (`nick`,`password`,`email`,`time_registered`,`time_last_seen`,`email_confirmed`,`activated`,`disabled`,`group`,`confirmation_code`) select %s as `nick`,`password`,`email`,UNIX_TIMESTAMP() as `time_registered`, UNIX_TIMESTAMP() as `time_last_seen`, `email_confirmed`, `activated`, `disabled`, `id` as `group`, `confirmation_code` from `ff_nickserv_core` where `id`=%s limit 1""", (source_s, groupid)) db_cursor.execute("select `nick` from `ff_nickserv_core` where `id`=%s limit 1", (groupid)) nickserv.sendMsg(source_s, "You are now in the group of \x02%s\x02.", db_cursor.fetchone()[0]) except Exception as e: nickserv.sendMsg(source_s, "Your nick cannot be grouped at this time.") log.error("Can't group %s in group #%d: %s", source_s, groupid, str(e))
def connect(self, addr): s = self.socket() if not s: s = self.socket(addr) if not s: return None try: s.connect(addr.sockaddr) except Exception as exc: err = exc.errno if err != errno.EINPROGRESS: log.error(exc, 'connect(%s) fail', addr.text) return None self.addr = addr log.trace(0, 'connection connect *%d: %s', self.index, addr.text) self.keepalive() return self
def testset_report(test_set, scope, version): """ Generates html reports for the given test execution. Paramters: ---------- - base_path: path containing all results of the execution """ fs.mkdir(fs.tests.path) template = None with open(fs.templates.resolve('gptTest_report_template.html'), 'r') as file: template = t.Template(file.read()) if template is None: log.error("Unable to load template") return percent = round(100 * len(test_set.passed_tests()) / len(test_set.tests), 2) html = template.generate(name=test_set.name, start_date=test_set.start_date, duration=f'{test_set.duration} s', scope=scope, operating_system=sys.platform, version=version, total=len(test_set.tests), failed_tests=len(test_set.failed_tests()), passed_tests=len(test_set.passed_tests()), percent=percent, real_duration=f'{test_set.real_duration} s', tests=test_set.tests) __generate_pie__(f'{test_set.name}_pie.png', len(test_set.passed_tests()), len(test_set.failed_tests()), len(test_set.skipped_tests())) with open(fs.tests.resolve(f'Report_{test_set.name}.html'), 'w') as file: file.write(html) # generate perofmance report for each test for test in test_set.tests: performance_report(test, version)
def main(): """ The main event to call, the bot connects to HoN and starts processing events. Disconnects should be caught and automatic re-connection can be handled. """ honbot = HoNBot('bot-brain') client = HoNBotClient(honbot) def sigint_handler(signal, frame): log.info("SIGINT, quitting") client.logout() sys.exit() signal.signal(signal.SIGINT, sigint_handler) reconnect_attempts = 0 while not honbot.is_quitting: time.sleep(1) # Cooling.. client.login() while client.is_logged_in and not honbot.is_quitting: if client.is_connected is True: # Reset the number of attempts. reconnect_attempts = 0 # Do some stuff if I want time.sleep(1) else: reconnect_attempts += 1 log.info("Disconnected from chat server") log.info("Reconnecting in 30 seconds (Attempts %d of 5)" % reconnect_attempts) time.sleep(30) try: client.connect() except ChatServerError, e: log.error(e)
log.info("Disconnecting...") if not self.is_connected: self.logged_in = False return try: self._chat_disconnect() except ChatServerError, e: log.error(e) log.info("Logging out...") try: self._logout() except MasterServerError, e: log.error(e) self.logged_in = False def on_auth_accepted(self, *p): """ Authenticated, join the default channels and set up some base things. """ log.info("Connected as %s" % self.account.nickname) self.bot.nickname = self.account.nickname for channel in self.channels.keys(): self.join_channel(channel) def on_joined_channel(self, channel, channel_id, topic, operators, users): log.info("\033[92mJoined \033[0m[%s - %s]" % (channel, topic)) if channel not in self.channels: self.channels[channel] = {'speaking' : True, 'learning': True}
def encode(self): import subprocess, re # Encode movie file with RVIO to send to the snapshot log.info("Encoding movie to send to snapshot") progress = 0 # @note: progressWindow is bogus - can't set the size, to have to fake the ultimate size by setting the # status message really large, then overwriting it with the real status. progressWindow( title = "Playblast Movie Encode", progress = progress, status = "---------------------------------------------------------------------------------------------------", isInterruptable=False) try: log.info("Getting local and server paths for %s" % self.shot) self.local_path = ("C:/temp/banzai_data/projects/%s/movies/%s" % (self.shot.show.code, self.shot.sequence.code)) self.local_file = "%s/%s" % (self.local_path, self.movie_file) # Make sure the directories exist first - create it if not, and bail if we fail if not self.create_dirs(self.local_path): log.error("Could not create local %s dir for playblast of %s" % (self.local_path, self.shot)) return if not self.create_dirs(self.server_path): log.error("Could not create server %s dir for playblast of %s" % (self.server_path, self.shot)) return log.info("Created local and server paths for the playblast of %s" % self.shot) encode_sp = None burn_in = "" if self.rv_support_path: burn_in = RvioInfo(self.shotfile, self.shot, self.sequence, self.show).burn_in_string() # RVIO can fail if there's not enough memory - @todo : this needs to be # tuned over time. threads = 4 free_memory = memory(freeMemory=True) frames = self.shot.frame_out - self.shot.frame_in if free_memory < 2000 and frames > 50: threads = 1 elif free_memory < 3000 and frames > 50: threads = 2 log.info("Utilizing %s cores to playblast and encode" % threads) if not self.shot.audio.exists(): log.info("Playblasting to snapshot without audio") encode_sp = subprocess.Popen( ('"%s/rvio" %s.%s-%s@@@@.iff -o %s \ %s \ -codec avc1 -quality .75 \ -outgamma 0.65 -v -outfps %i \ -rthreads %s' % ( self.rv_path, self.local_pblast_name, self.min_frame, self.max_frame, self.local_file, burn_in, self.shot.get_fps(), threads)), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) else: log.info("Playblasting to snapshot with audio") log.info("Audio path: %s" % self.shot.audio.path) encode_sp = subprocess.Popen( ('"%s/rvio" [ %s.%s-%s@@@@.iff %s ] -o %s \ %s \ -codec avc1 -quality .75 \ -outgamma 0.65 -v -outfps %i \ -rthreads %s' % ( self.rv_path, self.local_pblast_name, self.min_frame, self.max_frame, self.shot.audio.path, self.local_file, burn_in, self.shot.get_fps(), threads)), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) log.info("Encoding playblast with RVIO for %s" % self.shot) while True and encode_sp: # Continue reading from stdout until RVIO is finished, then break next_line = encode_sp.stdout.readline() if not next_line: break # Search for a % marker in the RVIO output, then "decode" it to get the % done if re.search("%", next_line): tmp = next_line.split("(")[1] tmp = tmp.split("%")[0] progress = int(float(tmp)) progressWindow( edit=True, progress=progress, status=('Encode: ' + next_line)) log.info(next_line.strip()) progress += 1 except: log.error("Something failed during playblast of %s : %s" % (self.shot, sys.exc_info()[0])) raise finally: # Ensure that we close the progressWindow, and unlock Maya for use progressWindow(endProgress=True)