# # File:: pipeline/projectutil/RAVE/data_convert.rb # Description:: RAVE data conversion functions. # # Author:: David Muir # Date:: 16 November 2009 # #---------------------------------------------------------------------------- # Uses #---------------------------------------------------------------------------- require 'pipeline/config/projects' require 'pipeline/config/project' require 'pipeline/log/log' require 'pipeline/os/path' require 'pipeline/util/environment' require 'pipeline/util/rage' include Pipeline require 'REXML/document' #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- module Pipeline module ProjectUtil module RAVE # # Return the Project and Branch objects for an Array of audio-filenames. # If the files belong to multiple projects or branches a RuntimeError # exception is raised. # # The optional block is executed with the project, branch and filename # String. # # == Example Usage # DHM TODO # def RAVE::get_project_from_filenames( filenames, &block ) raise ArgumentError.new( "Invalid Array of filenames (#{filenames.class})." ) \ unless ( filenames.is_a?( Array ) ) config = Pipeline::Config::instance() conv_project = nil conv_branch = nil filenames.each do |filename| throw IOError.new( "File #{filename} does not exist or is not readable." ) \ unless ( ::File::exists?( filename ) and ::File::readable?( filename ) ) filename = OS::Path::normalise( File::expand_path( filename ) ) config.projects.each_pair do |name, project| next unless ( filename.starts_with( project.root ) ) project.load_config( ) project.branches.each_pair do |branch_name, branch| next unless ( branch.is_audio_file?( filename ) ) throw RuntimeError.new( "Audio files from multiple projects, invalid conversion." ) \ unless ( conv_project.nil? or project == conv_project ) throw RuntimeError.new( "Audio files from multiple branches, invalid conversion." ) \ unless ( conv_branch.nil? or branch == conv_branch ) conv_project = project conv_branch = branch # Call user-block yield( conv_project, conv_branch, filename ) \ if ( block_given? and ( not ( conv_project.nil? or conv_branch.nil? ) ) ) end end end # Return project and branch. [ conv_project, conv_branch ] end # # Return project settings file for a particular Project. # def RAVE::get_project_settings_filename( project, branch = nil ) throw ArgumentError.new( "Invalid Project object (#{project.class})." ) \ unless ( project.is_a?( Pipeline::Project ) ) throw ArgumentError.new( "Invalid Branch object (#{branch.class})." ) \ unless ( branch.nil? or branch.is_a?( Pipeline::Branch ) ) env = Environment::new() branch.fill_env( env ) unless ( branch.nil? ) project.fill_env( env ) if ( branch.nil? ) env.subst( "$(audio)/ProjectSettings.xml" ) end # # Return project RAVE assets path. # def RAVE::get_project_assets_path( project, branch = nil ) throw ArgumentError.new( "Invalid Project object (#{project.class})." ) \ unless ( project.is_a?( Pipeline::Project ) ) throw ArgumentError.new( "Invalid Branch object (#{branch.class})." ) \ unless ( branch.nil? or branch.is_a?( Pipeline::Branch ) ) env = Environment.new() branch.fill_env( env ) unless ( branch.nil? ) project.fill_env( env ) if ( branch.nil? ) OS::Path::normalise( env.subst( "$(audio)/assets/Objects/" ) ) end # # Return RAVE metadata categories for a project/branch as a Hash, mapping # category String to input file(s) path. # # == Example Usage # DHM TODO. # def RAVE::get_project_metadata_tags( project, branch = nil ) settings_file = RAVE::get_project_settings_filename( project, branch ) tags = {} File::open( settings_file ) do |file| doc = REXML::Document.new( file ) doc.elements.each( 'ProjectSettings/MetadataSettings/MetadataFile' ) do |xml_node| name = xml_node.elements['Name'].text.to_s path = OS::Path::normalise( xml_node.elements['DataPath'].text.to_s ) tags[name] = path end end tags end # # Return RAVE metadata category for a project/branch and a particular # filename. The filename's path is matched based on its prefix directory, # so any file under a particular metadata directory should correctly be # determined. # # Returns nil if we cannot find a valid tag. Otherwise the tag as String # is returned. # def RAVE::get_project_metadata_tag_for_filename( project, branch, filename ) tags = RAVE::get_project_metadata_tags( project, branch ) prefix = RAVE::get_project_assets_path( project, branch ) filename = OS::Path::normalise( filename ) return ( nil ) unless ( filename.starts_with( prefix ) ) # Loop through our tags trying to find the correct tag for the path. tags.each do |name, path| fullpath = OS::Path::combine( prefix, path ) next unless ( filename.starts_with( fullpath ) ) return ( name ) end nil end # # Convert a file or Array of files from their absolute filename only. # The project, branch and mc.exe location is determined and the conversion # done. # # == Assumptions # Metadata compiler path: $(toolsbin)/mc/mc.exe. # def RAVE::data_convert_file( filenames, &block ) filenames = [ filenames ] unless ( filenames.is_a?( Array ) ) config = Pipeline::Config::instance( ) conv_project, conv_branch = RAVE::get_project_from_filenames( filenames ) env = Environment.new conv_branch.fill_env( env ) settings_file = RAVE::get_project_settings_filename( conv_project, conv_branch ) tags = get_project_metadata_tags( conv_project, conv_branch ) filenames.each do |filename| metadata = RAVE::get_project_metadata_tag_for_filename( conv_project, conv_branch, filename ) # For each project target. conv_project.targets.each do |platform, target| next unless ( target.enabled ) plat = RageUtils::rage_platform( platform ).upcase commandline = "$(toolsbin)/mc/mc.exe -project #{settings_file} -platform #{plat} -metadata #{metadata} -workingPath x:/" commandline = env.subst( commandline ) RAVE::log().info( "Starting RAVE metadata compiler..." ) RAVE::log().info( "#{commandline}" ) status, sout, serr = OS::start( commandline ) case status.exitstatus when 0 RAVE::log().info( "RAVE metadata compiler exited ok." ) sout.each do |m| RAVE::log().info( m ); end else RAVE::log().error( "Error invoking RAVE metadata compiler: #{status.exitstatus}." ) sout.each do |m| RAVE::log().info( m ); end serr.each do |m| RAVE::log().error( m ); end end end end end # Return module-wide log object. def RAVE::log() @@log = Log.new( 'rave' ) if ( @@log.nil? ) @@log end #------------------------------------------------------------------------ # Private #------------------------------------------------------------------------ private @@log = nil end # RAVE module end # ProjectUtil module end # Pipeline module # pipeline/projectutil/RAVE/data_convert.rb