Skip to content
Permalink
Browse files

[processing] Improve temporary directory handling

- Make the new Temp Folder setting optional, default to an empty
string, and note that empty = use default
- Move responsibility for cleanup of temporary folders to c++ (if
Processing Python part crashes, or doesn't exist, then we still
want these cleaned up correctly)
  • Loading branch information
nyalldawson committed Jan 9, 2020
1 parent efe5975 commit 06082a15c0ae8d798fb490b89e39efcec68a4b20
@@ -306,11 +306,6 @@ def unload(self):
self.toolbox.deleteLater()
self.menu.deleteLater()

# delete temporary output files
folder = QgsProcessingUtils.tempFolder()
if QDir(folder).exists():
shutil.rmtree(folder, True)

# also delete temporary help files
folder = tempHelpFolder()
if QDir(folder).exists():
@@ -62,7 +62,7 @@ class ProcessingConfig:
MAX_THREADS = 'MAX_THREADS'
DEFAULT_OUTPUT_RASTER_LAYER_EXT = 'DefaultOutputRasterLayerExt'
DEFAULT_OUTPUT_VECTOR_LAYER_EXT = 'DefaultOutputVectorLayerExt'
TEMP_PATH = 'TEMP_PATH'
TEMP_PATH = 'TEMP_PATH2'

settings = {}
settingIcons = {}
@@ -171,7 +171,7 @@ def initialize():
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.TEMP_PATH,
ProcessingConfig.tr('Temporary output folder path'), tempfile.gettempdir(),
ProcessingConfig.tr('Override temporary output folder path (leave blank for default)'), None,
valuetype=Setting.FOLDER))

@staticmethod
@@ -746,17 +746,31 @@ QVariant QgsProcessingUtils::generateIteratingDestination( const QVariant &input

QString QgsProcessingUtils::tempFolder()
{
static std::unique_ptr< QTemporaryDir > sTempFolder;
static QString sFolder;
static QMutex sMutex;
sMutex.lock();
if ( sFolder.isEmpty() || !sFolder.startsWith( QgsSettings().value( QStringLiteral( "Processing/Configuration/TEMP_PATH" ), QDir::tempPath() ).toString() ) )
QMutexLocker locker( &sMutex );
const QString basePath = QgsSettings().value( QStringLiteral( "Processing/Configuration/TEMP_PATH2" ) ).toString();
if ( basePath.isEmpty() )
{
QString subPath = QUuid::createUuid().toString().remove( '-' ).remove( '{' ).remove( '}' );
sFolder = QgsSettings().value( QStringLiteral( "Processing/Configuration/TEMP_PATH" ), QDir::tempPath() ).toString() + QStringLiteral( "/processing_" ) + subPath;
if ( !QDir( sFolder ).exists() )
QDir().mkpath( sFolder );
// default setting -- automatically create a temp folder. In this case, we use QTemporaryDir so
// that the folder is automatically deleted when QGIS is closed
if ( !sTempFolder )
{
const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( QDir::tempPath() );
sTempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
sFolder = sTempFolder->path();
}
}
else if ( sFolder.isEmpty() || !sFolder.startsWith( basePath ) || !sTempFolder )
{
const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( basePath );
// leak the previous folder -- we don't want it to be cleaned up, we don't know what was in it that may still
// be required for this session!
sTempFolder.release();
sTempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
sFolder = sTempFolder->path();
}
sMutex.unlock();
return sFolder;
}

@@ -8550,7 +8550,7 @@ void TestQgsProcessing::tempUtils()
// change temp folder in the settings
QgsSettings settings;
QString alternative_tempFolder1 = QStringLiteral( TEST_DATA_DIR ) + QStringLiteral( "/alternative_temp_test_one" );
settings.setValue( QStringLiteral( "Processing/Configuration/TEMP_PATH" ), alternative_tempFolder1 );
settings.setValue( QStringLiteral( "Processing/Configuration/TEMP_PATH2" ), alternative_tempFolder1 );
// check folder and if it's constant with alternative temp folder 1
tempFolder = QgsProcessingUtils::tempFolder();
QVERIFY( tempFolder.startsWith( alternative_tempFolder1 ) );
@@ -8562,7 +8562,7 @@ void TestQgsProcessing::tempUtils()
QVERIFY( alternativeTempFile1.startsWith( alternative_tempFolder1 ) );
// change temp folder in the settings again
QString alternative_tempFolder2 = QStringLiteral( TEST_DATA_DIR ) + QStringLiteral( "/alternative_temp_test_two" );
settings.setValue( QStringLiteral( "Processing/Configuration/TEMP_PATH" ), alternative_tempFolder2 );
settings.setValue( QStringLiteral( "Processing/Configuration/TEMP_PATH2" ), alternative_tempFolder2 );
// check folder and if it's constant constant with alternative temp folder 2
tempFolder = QgsProcessingUtils::tempFolder();
QVERIFY( tempFolder.startsWith( alternative_tempFolder2 ) );

0 comments on commit 06082a1

Please sign in to comment.
You can’t perform that action at this time.