# # File:: data_remove.rb # Description:: Functions for removing unused data. # # Author:: Marissa Warner-Wu # Date:: 19 June 2009 # #----------------------------------------------------------------------------- # Uses #----------------------------------------------------------------------------- require 'pipeline/os/file' require 'pipeline/util/rage_image' require 'pipeline/projectutil/data_extract' require 'pipeline/resourcing/path' require 'pipeline/config/targets' #----------------------------------------------------------------------------- # Implementation #----------------------------------------------------------------------------- module Pipeline module ProjectUtil #------------------------------------------------------------------------- # Functions #------------------------------------------------------------------------- # # == Description # A function which takes two image files and creates a new version of the # first image without any items which overlap with the second image. # # If file is only in image1 - adds this file to new image # If file is in both images - doesn't add # i.e. image1 - image2 = resulting image # # Compares based on file name. Also appends some log information to an # optional output file. # # === Example Usage # The code below would print the name of the new image. # # ProjectUtil::data_cull_image( ep_branch.project, ep_branch, target, r, root_independent_filename, ep_independent_filename, output_dir, map_log ) do |new_filename| # puts new_filename # end # def ProjectUtil::data_cull_image(proj, branch, target, r, image1, image2, output_dir, output_file = "", &block) # Start the builder builder = Util::RagebuilderImage.new( proj, branch, branch.targets[target] ) # Open the output file and write the name of the file log = nil count = 0 unless output_file == "" log = File.new(output_file, 'a') log.write "#{image1}\n" end # Extract the contents of the two images ready for comparison. image1_dest = OS::Path::combine( output_dir, 'image1' ) image2_dest = OS::Path::combine( output_dir, 'image2' ) image1_fullpath = [] image2_fullpath = [] image2_files = [] ProjectUtil::data_extract_image( r, image1, image1_dest ) do |extracted_filename| image1_fullpath << extracted_filename end ProjectUtil::data_extract_image( r, image2, image2_dest ) do |extracted_filename| image2_fullpath << extracted_filename image2_files << OS::Path::get_filename( extracted_filename ) end image_filename = OS::Path::combine( output_dir, OS::Path::get_trailing_directory( image1 ), OS::Path::get_filename( image1 ) ) builder.start # Iterate over the file lists comparing filenames that match. Images # have a flat directory structure so we don't need to worry about # sub-directories. If the output file is specified then use this as well. image1_fullpath.each do |image1_filename| image1_file = OS::Path::get_filename( image1_filename ) unless ( image2_files.include?( OS::Path::get_filename( image1_file ) ) ) # Only add this file if it is not present in image2 builder.add( image1_filename ) next end #If we're not adding this to the image then log it if log then log.write "\t\t\t#{image1_file}\n" count += 1 end end #image1_fullpath.each builder.save( image_filename ) builder.close if log then log.write "\tTOTAL: #{count}\n" log.close end yield( image_filename ) if ( block_given? ) # Clean up extracted files ::FileUtils::rm_r( image1_dest ) if ( ::File::directory?( image1_dest ) ) ::FileUtils::rm_r( image2_dest ) if ( ::File::directory?( image2_dest ) ) end #data_cull_image # # == Description # A function which takes a cutsprops.img file from one project and # compares it to cuts.img and cutsprops.img files from another project, # removing the items not used in the cutscenes. Logs output to a file, # cutsprops_compare_output.txt, in the output directory. # # Compares based on file name. # # === Example Usage # The code below would print the name of the new image. # # ProjectUtil::data_cull_cutsprops( root_branch.project, root_branch, target, r, root_cutsprops, ep_cuts1, ep_cutsprops1, ep_cuts2, ep_cutsprops2, output_dir ) do |new_filename| # puts new_filename # end # def ProjectUtil::data_cull_cutsprops(proj, branch, target, r, cutsprops1, cuts1, cutsprops2, cuts2, cutsprops3, output_dir, &block) puts "Output being written to cutsprops_compare_output.txt" # Start the builder builder = Util::RagebuilderImage.new( proj, branch, branch.targets[target] ) # Set up output file log_filename = OS::Path::combine( output_dir, 'cutsprops_compare_output.txt' ) log = File.new( log_filename, 'w') log.write("CUTSPROPS1: #{cutsprops1}\n") log.write("CUTSPROPS2: #{cutsprops2}\n\n") log.write("CUTSPROPS3: #{cutsprops3}\n\n") # Keep track of cutscenes which have had duplicate files removed duplicates = [] # Extract the contents of the two images for comparison and get lists of relevant files cutsprops1_dest = OS::Path::combine( output_dir, 'cutsprops1' ) cutsprops2_dest = OS::Path::combine( output_dir, 'cutsprops2' ) cuts_dest = OS::Path::combine( output_dir, 'cuts' ) cuts_files = [] ProjectUtil::data_extract_image( r, cutsprops1, cutsprops1_dest ) ProjectUtil::data_extract_image( r, cutsprops2, cutsprops2_dest ) ProjectUtil::data_extract_image( r, cutsprops3, cutsprops2_dest, true ) ProjectUtil::data_extract_image( r, cuts1, cuts_dest ) ProjectUtil::data_extract_image( r, cuts2, cuts_dest ) cuts_files = OS::FindEx::find_files_recurse( OS::Path::combine( cuts_dest, '*.cut*' ) ) image_filename = OS::Path::combine( output_dir, 'cutsprops.img' ) builder.start( ) # Iterate over the .cut files and add required assets to image used_assets = [] cuts_files.each do |cutscene| log.write("Parsing cutscene: #{cutscene}\n") text = [] assets = [] start = 0 finish = 0 # Parse for asset list File.open(cutscene, 'r') do text = IO.readlines( cutscene ) start = text.index( "[MODELS]\n" ) + 1 finish = text.index( "[/MODELS]\n" ) - 1 assets = text[start..finish] end # If this asset is used, add to the builder assets.each do |line| # Parse each line in the list for the item item = "" l = line.split[1] if l then item = l.downcase log.write("\t\t\t#{item} - ") else log.write("\t\t\tNIL - ") end # Check to see if we should skip this item if item == "" then log.write("skipped because nil\n") next end if item == "player" then log.write("skipped because player\n") next end if used_assets.include?( item ) then log.write("skipped because already added\n") next end cutsprops2_files = [] cutsprops2_files = OS::FindEx::find_files_recurse( OS::Path::combine( cutsprops2_dest, item + ".*" ) ) unless cutsprops2_files == [] then log.write("skipped because in cutsprops2 or 3\n") duplicates << cutscene next end # Otherwise, find all the related files and add to the image log.write("Searching for '" + OS::Path::combine( cutsprops1_dest, item + ".*" ) + "' " ) asset_files = OS::FindEx::find_files_recurse( OS::Path::combine( cutsprops1_dest, item + ".*" ) ) if asset_files == [] then log.write("[[ERROR: no asset files found for this item]]\n") next end used_assets << item log.write("adding to image:\n") asset_files.each do |file| log.write("\t\t\t\t\t#{file}\n") builder.add( file ) end end #assets.each end #cuts_files.each if duplicates == [] then log.write("==NO DUPLICATES FOUND\n") else log.write("==DUPLICATE FILES REMOVED FROM: #{duplicates}\n") end log.close builder.save( image_filename ) builder.close( ) yield( image_filename ) if ( block_given? ) # Clean up extracted files ::FileUtils::rm_r( cutsprops1_dest ) if ( ::File::directory?( cutsprops1_dest ) ) ::FileUtils::rm_r( cutsprops2_dest ) if ( ::File::directory?( cutsprops2_dest ) ) ::FileUtils::rm_r( cuts_dest ) if ( ::File::directory?( cuts_dest ) ) end #data_cull_cutsprops # # == Description # A function which replaces a given cuts image with a dummy file. The .cut # files are replaced with empty files and the .iad files are replaced with a # given template. The resulting image is passed to an optional given block. # # === Example Usage # The code below would print the name of the new image. # # ProjectUtil::data_dummy_cuts( root_branch.project, root_branch, target, r, root_cuts, template_filename, output_dir ) do |new_filename| # puts new_filename # end # def ProjectUtil::data_dummy_cuts(proj, branch, target, r, image, template_file, output_dir, &block) throw ArgumentError.new( "Invalid target object (#{target.class})." ) \ unless ( target.is_a?( Pipeline::Target ) ) throw ArgumentError.new( "Template file does not exist (#{template_file})." ) \ unless ( File.exist?(template_file) ) # Start the builder builder = Util::RagebuilderImage.new( proj, branch, target ) # Read the template file template = IO.read(template_file) # Extract the contents of the image to a temporary folder image_dest = OS::Path::combine( output_dir, 'dummy_cuts' ) image_fullpath = [] ProjectUtil::data_extract_image( r, image, image_dest ) do |extracted_filename| image_fullpath << extracted_filename end new_image_filename = OS::Path::combine( output_dir, OS::Path::get_filename( image ) ) builder.start( ) # Iterate over the list of extracted files and replaces them image_fullpath.each do |image_filename| #target_filename = Resourcing::convert_independent_filename_to_platform( image_filename, target ) if OS::Path::get_extension( image_filename ) == "cut" then f = File.new( image_filename, 'w' ) f.write( "[CUTSCENE_HEADER]\n1 1 1 1\n[/CUTSCENE_HEADER]\n" ) f.close elsif OS::Path::get_extension( image_filename ) == "iad" then f = File.new( image_filename, 'w' ) f.write( template ) f.close else puts "ERROR: #{image_filename} is not a .cut or a .iad file, skipping" next end builder.add( image_filename ) end #image_fullpath.each builder.save( new_image_filename ) builder.close( ) yield( new_image_filename ) if ( block_given? ) # Clean up extracted files ::FileUtils::rm_r( image_dest ) if ( ::File::directory?( image_dest ) ) end #data_dummy_cuts # # == Description # A function which replaces a given image with a dummy image. All the # files inside the image are extracted, replaced with dummies, and then # repacked. The resulting image is passed to an optional given block. # # === Example Usage # The code below would print the name of the new image. # # ProjectUtil::data_dummy_image( root_branch.project, root_branch, target, r, root_cuts, output_dir ) do |new_filename| # puts new_filename # end # def ProjectUtil::data_dummy_image(proj, branch, target, r, image, output_dir, &block) throw ArgumentError.new( "Invalid target object (#{target.class})." ) \ unless ( target.is_a?( Pipeline::Target ) ) # Start the builder builder = Util::RagebuilderImage.new( proj, branch, target ) # Extract the contents of the image to a temporary folder image_dest = OS::Path::combine( output_dir, 'dummy_image' ) image_fullpath = [] ProjectUtil::data_extract_image( r, image, image_dest ) do |extracted_filename| image_fullpath << extracted_filename end new_image_filename = OS::Path::combine( output_dir, OS::Path::get_filename( image ) ) builder.start( ) # Iterate over the list of extracted files and replaces with with empty target files image_fullpath.each do |image_filename| target_filename = Resourcing::convert_independent_filename_to_platform( image_filename, target ) puts target_filename f = File.new( target_filename, 'w') f.write('x') builder.add( target_filename ) f.close end #image_fullpath.each builder.save( new_image_filename ) builder.close( ) yield( new_image_filename ) if ( block_given? ) # Clean up extracted files ::FileUtils::rm_r( image_dest ) if ( ::File::directory?( image_dest ) ) end #data_dummy_image end # ProjectUtil module end # Pipeline module # data_remove.rb