from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import datetime import os import smtplib import sys # *** SETTINGS *** # SMTP email notification settings SMTP_HOST = 'smtp.rockstar.t2.corp' SMTP_PORT = 25 SMTP_USERNAME = '' SMTP_PASSWORD = '' SMTP_FROM = 'Audio RPFs Generator ' SMTP_TO = ( 'Matt Hailey ', 'Alastair MacGregor ', #'Matthew Smith ', ) # Logging LOG_PATH = None PRINT_LOG = True warning_count = 0 error_count = 0 logger = '' # Perforce PERFORCE_EXE_NAME = r'p4' # Environment env_args_keys = ( 'build', 'audio', 'platform', 'ragebuilder', 'package', 'RS_TOOLSROOT', 'RS_BUILDBRANCH', ) env_args = {} packlist_path = None input_path = None output_path = None build_pack_path = None working_path = None # *** SETTINGS (END) *** # *** TYPES *** # LogSeverity enums class LogSeverity: INFO='INFO' WARNING='WARNING' ERROR='ERROR' CRITICAL='CRITICAL' # *** TYPES (END) *** # *** MAIN PROCESS *** def main(): # Run process args = sys.argv # Fetch required environment variables if not init_env_vars(env_args_keys, env_args): log("Failed to load all required environment variables", LogSeverity.ERROR) return -1 # Initialise paths to required dirs and files if not init_paths(): log("Failed to initialise paths", LogSeverity.ERROR) return -1 set_working_path(env_args['build']) # Mark packlist file for edit if not run_p4_cmd('edit', packlist_path): return -1 # Generate RPF files rebuild = 'full' in args if not generate_rpfs(rebuild): return -1 # Execute RAGE builder if not exec_rage_builder(): return -1 # Revert any unchanged files platform = env_args['platform'] if platform.upper() == 'PC': platform = 'x64' path = os.path.join(env_args['build'], platform, 'audio') args = '-a %s\\...' % path if not run_p4_cmd('revert', args): return return 0 def init_paths(): global packlist_path global input_path global output_path global build_pack_path # Check build path exists if not os.path.exists(env_args['build']): log("Path does not exist: %s" % env_args['build'], LogSeverity.ERROR) return False log("Using build path: %s" % env_args['build'], LogSeverity.INFO) # Init config dir config_dir = os.path.join(env_args['audio'], env_args['platform'], 'config') if not os.path.exists(config_dir): log("Creating path: %s" % config_dir, LogSeverity.INFO) os.makedirs(config_dir) # Init packlist path (file may not exist locally) packlist_path = os.path.join(config_dir, 'packlist.txt') log("Using packlist path: %s" % packlist_path, LogSeverity.INFO) # Init input path input_path = os.path.join(env_args['audio'], env_args['platform'], 'sfx') if not os.path.exists(input_path): log("Path does not exist: %s" % input_path, LogSeverity.ERROR) return False log("Using input path: %s" % input_path, LogSeverity.INFO) # Init output path platform = env_args['platform'] if platform.upper() == 'PC': platform = 'x64' output_path = os.path.join(env_args['build'], platform, 'audio', 'sfx') if not os.path.exists(output_path): log("Path does not exist - creating directory: %s" % output_path, LogSeverity.INFO) try: os.makedirs(output_path) except: log("Failed to create directory: %s" % output_path, LogSeverity.ERROR) return False log("Using output path: %s" % output_path, LogSeverity.INFO) # Init build pack path build_pack_path = os.path.join(env_args['RS_TOOLSROOT'], 'bin', 'audio', 'scripts', 'RPFs', 'build_pack.bat') if not os.path.exists(build_pack_path): log("Path does not exist: %s" % build_pack_path, LogSeverity.ERROR) return False log("Using build pack path: %s" % build_pack_path, LogSeverity.INFO) return True def generate_rpfs(rebuild): global input_path global output_path if rebuild: log("Generating all audio RPF files..", LogSeverity.INFO) else: log("Generating latest audio RPF files..", LogSeverity.INFO) # Open pack list file for writing and overwrite previous data pack_list_file = open(packlist_path, 'w') # Generate RPFs for files in each pack (ie sub-dir) in input_path for path, packs, files in os.walk(input_path): for pack in packs: # Pack needs to be added to pack list file pack_list_file.write("%s\n" % pack) if not rebuild and not pack_requires_build(os.path.join(path, pack), pack): # Skip current pack if build not required and # process not marked for full rebuild continue # Init build params log("Building pack %s..." % pack, LogSeverity.INFO) input_pack_path = os.path.join(input_path, pack) output_pack_path = os.path.join(output_path, pack) # Run build command cmd = r'%s %s\ %s.rpf %s' % (build_pack_path, input_pack_path, output_pack_path, pack) log("Running cmd: %s" % cmd, LogSeverity.INFO) if os.system(cmd) != 0: log("Failed to successfully run command: %s" % cmd, LogSeverity.ERROR) return False pack_list_file.close() return True def pack_requires_build(pack_path, pack_name): global output_path rpf_path = '%s.rpf' % os.path.join(output_path, pack_name) # If output file doesn't exist, it needs to be built if not os.path.exists(rpf_path): return True for file in os.listdir(pack_path): # Only interested in AWC files if file.lower().endswith('.awc'): awc_path = os.path.join(pack_path, file) # If AWC file is newer than RPF file, it needs to be built if os.stat(awc_path).st_mtime > os.stat(rpf_path).st_mtime: return True return False def exec_rage_builder(): platform = env_args['platform'] if platform.upper() == 'PC': platform = 'x64' pack = os.path.join(env_args['build'], platform, 'audio', 'audio.rpf') rootpath = os.path.join(env_args['audio'], env_args['platform']) cmd = '%s %s -pack %s -rootpath %s\ -extignore .awc -nameheapshift=1' % \ (env_args['ragebuilder'], env_args['package'], pack, rootpath) # Mark pack file for edit if not run_p4_cmd('edit', pack): return False log("Running cmd: %s" % cmd, LogSeverity.INFO) if os.system(cmd) != 0: log("Failed to successfully run command: %s" % cmd, LogSeverity.ERROR) return False return True # *** MAIN PROCESS (END) *** # *** HELPER FUNCTIONS *** def set_working_path(path): global working_path # Change working path if required if working_path != path: working_path = path msg = "Setting working path as %s" % path log(msg, LogSeverity.INFO) os.chdir(path) def init_env_vars(keys, output): log("Loading environment variables...", LogSeverity.INFO) successful = True for key in keys: try: value = os.environ[key] output[key] = value log("Loaded environment variable: %s=%s" % (key, value), LogSeverity.INFO) except: log("Failed to load environment variable: %s" % key, LogSeverity.ERROR) successful = False return successful def log(msg, severity): global warning_count global error_count global logger now = datetime.datetime.now() now_str = now.strftime('%H:%M:%S') full_msg = "[%s] %s: %s" % (now_str, severity, msg) # Print to console if required if PRINT_LOG: print full_msg # Increment warning/error counter if severity == LogSeverity.WARNING: warning_count += 1 elif severity in (LogSeverity.ERROR, LogSeverity.CRITICAL): error_count += 1 # Store message in logger logger += "%s\n" % full_msg def save_log(): # Save log of current process to file if LOG_PATH: if not os.path.exists(LOG_PATH): os.makedirs(LOG_PATH) writer = open(LOG_PATH, 'w') writer.write(logger) writer.close() def run_p4_cmd(action, args): cmd = '%s %s %s' % (PERFORCE_EXE_NAME, action, args) log("Running Perforce cmd: %s" % cmd, LogSeverity.INFO) if os.system(cmd) != 0: log("Failed to successfully run P4 command: %s" % cmd, LogSeverity.ERROR) return False return True # *** HELPER FUNCTIONS (END) *** if __name__ == '__main__': main()