User Tools

Site Tools


File Copying

Summary

Below is an example demonstrating how you can obtain a [recursive] list of files from a given folder (e.g., Figure Metrics configuration files, part of the Measure Metrics product) and recursively copy them to another folder.

API Areas of Interest

Example

File_Copy_Figure_Metrics_Configs.dsa
// Define an anonymous function;
// serves as our main loop,
// limits the scope of variables
(function(){
 
	// Define "globals" for identifying the script
	var g_sScript = getScriptFileName();
	var g_oFileInfo = new DzFileInfo( g_sScript );
 
	// Initialize 'static' variables that hold modifier key state
	var s_bShiftPressed = false;
	var s_bControlPressed = false;
	var s_bAltPressed = false;
	var s_bMetaPressed = false;
 
	// If the "Action" global transient is defined, and its the correct type
	if( typeof( Action ) != "undefined" && Action.inherits( "DzScriptAction" ) ){
		// If the current key sequence for the action is not pressed
		if( !App.isKeySequenceDown( Action.shortcut ) ){
			updateModifierKeyState();
		}
	// If the "Action" global transient is not defined
	} else if( typeof( Action ) == "undefined" ) {
		updateModifierKeyState();
	}
 
	/*********************************************************************/
	// void : A function for updating the keyboard modifier state
	function updateModifierKeyState()
	{
		// Get the current modifier key state
		var nModifierState = App.modifierKeyState();
		// Update variables that hold modifier key state
		s_bShiftPressed = (nModifierState & 0x02000000) != 0;
		s_bControlPressed = (nModifierState & 0x04000000) != 0;
		s_bAltPressed = (nModifierState & 0x08000000) != 0;
		s_bMetaPressed = (nModifierState & 0x10000000) != 0;
	};
 
	/*********************************************************************/
	// void : A function for printing only if debugging
	function debug()
	{
		// If we are not debugging
		if( !s_bAltPressed ){
			// We are done...
			return;
		}
 
		// Convert the arguments object into an array
		var aArguments = [].slice.call( arguments );
 
		// Print the array
		print( aArguments.join(" ") );
	};
 
	/*********************************************************************/
	// String : A function for retrieving a translation if one exists
	function text( sText )
	{
		// If the version of the application supports qsTr()
		if( typeof( qsTr ) != "undefined" ){
			// Return the translated (if any) text
			return qsTr( sText );
		}
 
		// Return the original text
		return sText;
	};
 
	/***********************************************************************
	***** DsFileSystem Prototype *****
	***********************************************************************/
 
	/*********************************************************************/
	function DsFileSystem()
	{
	};
 
	/***********************************************************************/
	DsFileSystem.superclass = Object;
 
	/*********************************************************************/
	// Array<String|DzDir> : Method for collecting an array of directory objects
	DsFileSystem.prototype.getDirectories = function( oDir, regxFilter, nFilter, nSort, sType, bRecurse )
	{
		// Provide feedback
		debug( String("DsFileSystem::getDirectories( %1, \"%2\", %3, %4, \"%5\", %6 )")
			.arg( oDir.path() )
			.arg( regxFilter )
			.arg( nFilter )
			.arg( nSort )
			.arg( sType )
			.arg( bRecurse ) );
 
		// Declare working variable
		var sAbsPath;
 
		// Get the directory names
		var aDirs = oDir.entryList( regxFilter, nFilter, nSort );
		// Iterate over the directory names
		for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){
			// Get the absolute path of the 'current' dir
			sAbsPath = String( "%1/%2" ).arg( oDir.absPath() ).arg( aDirs[ i ] );
			// Based on the type requested
			switch( sType ){
				default:
				case "String":
					// Update the name with the absolute path of the directory
					aDirs[ i ] = sAbsPath;
					// If we are recursing
					if( bRecurse ){
						// Recursively collect the directory paths
						aDirs = aDirs.concat( this.getSubDirectories( new DzDir( sAbsPath ),
							regxFilter, nFilter, nSort, sType ) );
					}
					break;
				case "DzDir":					
					// Update the name with a directory object
					aDirs[ i ] = new DzDir( sAbsPath );
					// If we are recursing
					if( bRecurse ){
						// Recursively collect the directories
						aDirs = aDirs.concat( this.getSubDirectories( aDirs[ i ],
							regxFilter, nFilter, nSort, sType ) );
					}
					break;
			}
		}
 
		// Return the result
		return aDirs;
	};
 
	/*********************************************************************/
	// Array<String|DzDir> : Method for recursively collecting an array of directory objects
	DsFileSystem.prototype.getSubDirectories = function( oDir, regxFilter, nFilter, nSort, sType )
	{
		// Provide feedback
		debug( String( "DsFileSystem::getSubDirectories( %1, \"%2\", %3, %4, \"%5\" )" )
			.arg( oDir.path() )
			.arg( regxFilter )
			.arg( nFilter )
			.arg( nSort )
			.arg( sType ) );
 
		// Get the immediate child directories
		var aDirs = this.getDirectories( oDir, regxFilter, nFilter, nSort, sType, true );
		// Iterate over the directories
		for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){
			// Based on the type requested
			switch( sType ){
				default:
				case "String":
					// Recursively collect the directory paths
					aDirs = aDirs.concat( this.getSubDirectories( new DzDir( aDirs[ i ] ),
						regxFilter, nFilter, nSort, sType ) );
					break;
				case "DzDir":	
					// Recursively collect the directories
					aDirs = aDirs.concat( this.getSubDirectories( aDirs[ i ],
						regxFilter, nFilter, nSort, sType, true ) );
					break;
			}
		}
 
		// Return the result
		return aDirs;
	};
 
	/*********************************************************************/
	// Array<String|DzFileInfo|DzFile> : Method for collecting an array of files
	DsFileSystem.prototype.getFiles = function( oDir, regxFilter, nFilter, nSort, sType )
	{
		// Provide feedback
		debug( String( "DsFileSystem::getFiles( %1, \"%2\", %3, %4, \"%5\" )" )
			.arg( oDir.path() )
			.arg( regxFilter )
			.arg( nFilter )
			.arg( nSort )
			.arg( sType ) );
 
		// Declare working variable
		var sAbsFilePath;
 
		// Get the file names
		var aFiles = oDir.entryList( regxFilter, nFilter, nSort );
		// Iterate over the file names
		for( var i = 0, nFiles = aFiles.length; i < nFiles; i += 1 ){
			// Get the absolute path of the 'current' file
			sAbsFilePath = oDir.absFilePath( aFiles[ i ] );
			// Based on the type requested
			switch( sType ){
				default:
				case "String":
					// Update the name with the absolute path of a file
					aFiles[ i ] = sAbsFilePath;
					break;
				case "DzFileInfo":
					// Update the name with a file info object
					aFiles[ i ] = new DzFileInfo( sAbsFilePath );
					break;
				case "DzFile":
					// Update the name with a file object
					aFiles[ i ] = new DzFile( sAbsFilePath );
					break;
			}
		}
 
		// Return the result
		return aFiles;
	};
 
	/*********************************************************************/
	// Array<String|DzDir> : Method for retrieving a list of directories
	DsFileSystem.prototype.getDirectoryList = function( sPath, sFilter, sType, bRecurse, bRelative )
	{
		// Declare the output
		var aDirs = [];
 
		// Create a directory object
		var oBaseDir = new DzDir( sPath );
		// If the directory doesn't exist
		if( !oBaseDir.exists() ){
			// We are done...
			return aDirs;
		}
 
		// Get the directories
		var aDirs = this.getDirectories( oBaseDir, sFilter,
			DzDir.Dirs | DzDir.NoDotAndDotDot, DzDir.Name, sType, bRecurse );
 
		// If we do not want relative
		if( !bRelative ){
			// Return the result
			return aDirs;
		}
 
		// Declare working variable
		var sAbsPath, sRelPath;
		var oDir;
 
		// Iterate over the directories
		for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){
			// Based on the type requested
			switch( sType ){
				default:
				case "String":
					// Get the 'current' path
					sAbsPath = aDirs[ i ];
					// Get the relative portion of the path
					sRelPath = sAbsPath.substring( sPath.length );
					// Update the path
					aDirs[ i ] = sRelPath;
					break;
				case "DzDir":
					// Get the 'current' directory
					oDir = aDirs[ i ];
					// Get the path
					sAbsPath = oDir.path();
					// Get the relative portion of the path
					sRelPath = sAbsPath.substring( sPath.length );
					// Update the path
					oDir.setPath( sRelPath );
					// Update the directory
					aDirs[ i ] = oDir;
					break;
			}
		}
 
		// Return the result
		return aDirs;
	};
 
	/*********************************************************************/
	// Array<String|DzFileInfo|DzFile> : Method for retrieving a list of files
	DsFileSystem.prototype.getFileList = function( sPath, sFilter, sType, bRecurse )
	{
		// Declare the output
		var aFiles = [];
 
		// Get the directories
		var aDirs = this.getDirectoryList( sPath, "*", "DzDir", bRecurse );
		// Iterate over the directories
		for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){
			// Append the files from the 'current' directory to the output
			aFiles = aFiles.concat(
				this.getFiles( aDirs[ i ], sFilter, DzDir.Files, DzDir.Name, sType ) );
		}
 
		// Return the result
		return aFiles;
	};
 
	/*********************************************************************/
	// String : A function for prompting the user to pick from a list
	function promptUserChoice( sLabel, aChoices )
	{
		// Create a basic dialog
		var wDlg = new DzBasicDialog();
 
		// Get the wrapped widget for the dialog
		var oDlgWgt = wDlg.getWidget();
 
		// Get the name of this file
		var sName = g_oFileInfo.baseName();
 
		// Set the title of the dialog
		wDlg.caption = sName.replace( /_/g, " " );
 
		// Strip the space for a settings key
		var sKey = String("%1Dlg").arg( sName.replace( / /g, "" ) );
 
		// Set an [unique] object name on the wrapped dialog widget;
		// this is used for recording position and size separately
		// from all other [uniquely named] DzBasicDialog instances
		oDlgWgt.objectName = sKey;
 
		// Create a label
		var wLabel = new DzLabel( wDlg );
		// Set its text
		wLabel.text = sLabel;
		// Add the widget to the dialog
		wDlg.addWidget( wLabel );
 
		// Create a combobox
		var wChoicesCmb = new DzComboBox( wDlg );
		// Populate the choices
		wChoicesCmb.addItems( aChoices );
		// Add the widget to the dialog
		wDlg.addWidget( wChoicesCmb );
 
		// Get the minimum size for the dialog
		var sizeHint = oDlgWgt.minimumSizeHint;
 
		// Set the fixed size to the minimum size
		wDlg.setFixedSize( sizeHint.width, sizeHint.height );
 
		// If the user cancels the dialog
		if( !wDlg.exec() ){
			// We are done...
			return "";
		}
 
		// return the user's choice
		return wChoicesCmb.currentText;
	};
 
	/*********************************************************************/
	// Get the application data directory
	var oAppDataDir = new DzDir( App.getAppDataPath() );
 
	//
	var sTgtDataDir = oAppDataDir.path();
	debug( "Target =", sTgtDataDir );
 
	// Get the words in the application name
	var aAppName = App.appName.split(" ");
	// Get the numbers in the version
	var aVersion = App.versionString.split(".");
 
	// Construct the name of the (general release) application data folder
	var sFolderName = String("%1%2").arg( aAppName[ aAppName.length - 1 ] ).arg( aVersion[ 0 ] );
 
	// Initialize to the application data directory
	var oSrcDataDir = new DzDir( sTgtDataDir );
	// Go up a directory
	oSrcDataDir.cdUp();
 
	// Get a list of the directory names that start with the prefix we want
	var aAppDataDirs = oSrcDataDir.entryList( String("%1*").arg( sFolderName ), DzDir.Dirs | DzDir.NoDotAndDotDot );
	// Get the index of the current directory in the list
	var nSelf = aAppDataDirs.indexOf( oAppDataDir.dirName() );
	// Remove the current directory from the list
	aAppDataDirs.splice( nSelf, 1 );
 
	// Prompt the user for which channel to copy from
	var sFolder = promptUserChoice( text( "Copy Figure Metrics files from:" ), aAppDataDirs );
	// If the user cancelled
	if( sFolder.isEmpty() ){
		// We are done...
		return;
	}
 
	// Let the user know we are busy
	setBusyCursor();
 
	// Change the directory to the one chosen by the user
	oSrcDataDir.cd( sFolder );
 
	//
	var sSrcDataDir = oSrcDataDir.path();
	debug( "Source =", sSrcDataDir );
 
	// Create a file system object
	var oFileSystem = new DsFileSystem();
 
	var oTgtFile;
	var sSrcFile, sTgtFile, sRelFile;
 
	// Get the list of files that match the filters
	var aSrcFiles = oFileSystem.getFileList( sSrcDataDir, "*.json", "String", true );
	// Iterate over the file paths
	for( var i = 0, nFiles = aSrcFiles.length; i < nFiles; i += 1 ){
		// Get the 'current' source file path
		sSrcFile = aSrcFiles[ i ];
		// Get the relative portion of the file path
		sRelFile = sSrcFile.substring( sSrcDataDir.length );
		// Construct the target file path
		sTgtFile = sTgtDataDir + sRelFile;
		// Create a file info object
		oTgtFile = new DzFileInfo( sTgtFile );
		// Ensure the target path exists
		if( oAppDataDir.mkpath( oTgtFile.absolutePath() ) ){
			// Copy the source file to the target path
			oSrcDataDir.copy( sSrcFile, sTgtFile );
		}
		// Do not leak memory
		oTgtFile.deleteLater();
	}
 
	// Let the user know we are done
	clearBusyCursor();
 
// Finalize the function and invoke
})();