Skip to content

Commit

Permalink
Merge pull request #52198 from nirvn/qgsziputils_imp
Browse files Browse the repository at this point in the history
[api] Add a new QgsZipUtils's files() function and a unzip() parameter to skip consistency check
  • Loading branch information
nirvn committed Mar 14, 2023
2 parents f77c4c8 + 4caeb63 commit 45f54b6
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
10 changes: 9 additions & 1 deletion python/core/auto_generated/qgsziputils.sip.in
Expand Up @@ -25,12 +25,13 @@ extension, ``False`` otherwise.
:return: ``True`` if the file is zipped, ``False`` otherwise
%End

bool unzip( const QString &zip, const QString &dir, QStringList &files /Out/ );
bool unzip( const QString &zip, const QString &dir, QStringList &files /Out/, bool checkConsistency = true );
%Docstring
Unzip a zip file in an output directory.

:param zip: The zip filename
:param dir: The output directory
:param checkConsistency: Perform additional stricter consistency checks on the archive, and error if they fail (since QGIS 3.30)

:return: - ``False`` if the zip filename does not exist, the output directory
- files: The absolute path of unzipped files
Expand All @@ -55,6 +56,13 @@ also returned.



const QStringList files( const QString &zip );
%Docstring
Returns the list of files within a ``zip`` file

.. versionadded:: 3.30
%End

};

/************************************************************************
Expand Down
36 changes: 34 additions & 2 deletions src/core/qgsziputils.cpp
Expand Up @@ -34,7 +34,7 @@ bool QgsZipUtils::isZipFile( const QString &filename )
return QFileInfo( filename ).suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) == 0;
}

bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QStringList &files )
bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QStringList &files, bool checkConsistency )
{
files.clear();

Expand Down Expand Up @@ -66,7 +66,7 @@ bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QString

int rc = 0;
const QByteArray fileNamePtr = zipFilename.toUtf8();
struct zip *z = zip_open( fileNamePtr.constData(), ZIP_CHECKCONS, &rc );
struct zip *z = zip_open( fileNamePtr.constData(), checkConsistency ? ZIP_CHECKCONS : 0, &rc );

if ( rc == ZIP_ER_OK && z )
{
Expand Down Expand Up @@ -293,3 +293,35 @@ bool QgsZipUtils::encodeGzip( const QByteArray &bytesIn, QByteArray &bytesOut )
deflateEnd( &strm );
return true;
}

const QStringList QgsZipUtils::files( const QString &zip )
{
if ( zip.isEmpty() && !QFileInfo::exists( zip ) )
{
return QStringList();
}
QStringList files;

int rc = 0;
const QByteArray fileNamePtr = zip.toUtf8();
struct zip *z = zip_open( fileNamePtr.constData(), 0, &rc );

if ( rc == ZIP_ER_OK && z )
{
const int count = zip_get_num_files( z );
if ( count != -1 )
{
struct zip_stat stat;

for ( int i = 0; i < count; i++ )
{
zip_stat_index( z, i, 0, &stat );
files << QString( stat.name );
}
}

zip_close( z );
}

return files;
}
10 changes: 9 additions & 1 deletion src/core/qgsziputils.h
Expand Up @@ -42,11 +42,12 @@ namespace QgsZipUtils
* \param zip The zip filename
* \param dir The output directory
* \param files The absolute path of unzipped files
* \param checkConsistency Perform additional stricter consistency checks on the archive, and error if they fail (since QGIS 3.30)
* \returns FALSE if the zip filename does not exist, the output directory
* does not exist or is not writable.
* \since QGIS 3.0
*/
CORE_EXPORT bool unzip( const QString &zip, const QString &dir, QStringList &files SIP_OUT );
CORE_EXPORT bool unzip( const QString &zip, const QString &dir, QStringList &files SIP_OUT, bool checkConsistency = true );

/**
* Zip the list of files in the zip file. If the zip file already exists or is
Expand Down Expand Up @@ -83,6 +84,13 @@ namespace QgsZipUtils
*/
CORE_EXPORT bool encodeGzip( const QByteArray &bytesIn, QByteArray &bytesOut ) SIP_SKIP;

/**
* Returns the list of files within a \a zip file
*
* \since QGIS 3.30
*/
CORE_EXPORT const QStringList files( const QString &zip );

};

#endif //QGSZIPUTILS_H
13 changes: 13 additions & 0 deletions tests/src/python/test_qgsziputils.py
Expand Up @@ -121,6 +121,19 @@ def test_zip_unzip_ok(self):
self.assertTrue(rc)
self.assertEqual(len(files), 3)

def test_zip_files(self):
zip = tmpPath()

f0 = os.path.join(unitTestDataPath(), 'multipoint.shp')
f1 = os.path.join(unitTestDataPath(), 'lines.shp')
f2 = os.path.join(unitTestDataPath(), 'joins.qgs')

rc = QgsZipUtils.zip(zip, [f0, f1, f2])
self.assertTrue(rc)

files = QgsZipUtils.files(zip)
self.assertEqual(files, ['multipoint.shp', 'lines.shp', 'joins.qgs'])


if __name__ == '__main__':
unittest.main()

0 comments on commit 45f54b6

Please sign in to comment.