Skip to content

Commit 45f54b6

Browse files
authoredMar 14, 2023
Merge pull request #52198 from nirvn/qgsziputils_imp
[api] Add a new QgsZipUtils's files() function and a unzip() parameter to skip consistency check
2 parents f77c4c8 + 4caeb63 commit 45f54b6

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed
 

‎python/core/auto_generated/qgsziputils.sip.in

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ extension, ``False`` otherwise.
2525
:return: ``True`` if the file is zipped, ``False`` otherwise
2626
%End
2727

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

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

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

5657

5758

59+
const QStringList files( const QString &zip );
60+
%Docstring
61+
Returns the list of files within a ``zip`` file
62+
63+
.. versionadded:: 3.30
64+
%End
65+
5866
};
5967

6068
/************************************************************************

‎src/core/qgsziputils.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ bool QgsZipUtils::isZipFile( const QString &filename )
3434
return QFileInfo( filename ).suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) == 0;
3535
}
3636

37-
bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QStringList &files )
37+
bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QStringList &files, bool checkConsistency )
3838
{
3939
files.clear();
4040

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

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

7171
if ( rc == ZIP_ER_OK && z )
7272
{
@@ -293,3 +293,35 @@ bool QgsZipUtils::encodeGzip( const QByteArray &bytesIn, QByteArray &bytesOut )
293293
deflateEnd( &strm );
294294
return true;
295295
}
296+
297+
const QStringList QgsZipUtils::files( const QString &zip )
298+
{
299+
if ( zip.isEmpty() && !QFileInfo::exists( zip ) )
300+
{
301+
return QStringList();
302+
}
303+
QStringList files;
304+
305+
int rc = 0;
306+
const QByteArray fileNamePtr = zip.toUtf8();
307+
struct zip *z = zip_open( fileNamePtr.constData(), 0, &rc );
308+
309+
if ( rc == ZIP_ER_OK && z )
310+
{
311+
const int count = zip_get_num_files( z );
312+
if ( count != -1 )
313+
{
314+
struct zip_stat stat;
315+
316+
for ( int i = 0; i < count; i++ )
317+
{
318+
zip_stat_index( z, i, 0, &stat );
319+
files << QString( stat.name );
320+
}
321+
}
322+
323+
zip_close( z );
324+
}
325+
326+
return files;
327+
}

‎src/core/qgsziputils.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ namespace QgsZipUtils
4242
* \param zip The zip filename
4343
* \param dir The output directory
4444
* \param files The absolute path of unzipped files
45+
* \param checkConsistency Perform additional stricter consistency checks on the archive, and error if they fail (since QGIS 3.30)
4546
* \returns FALSE if the zip filename does not exist, the output directory
4647
* does not exist or is not writable.
4748
* \since QGIS 3.0
4849
*/
49-
CORE_EXPORT bool unzip( const QString &zip, const QString &dir, QStringList &files SIP_OUT );
50+
CORE_EXPORT bool unzip( const QString &zip, const QString &dir, QStringList &files SIP_OUT, bool checkConsistency = true );
5051

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

87+
/**
88+
* Returns the list of files within a \a zip file
89+
*
90+
* \since QGIS 3.30
91+
*/
92+
CORE_EXPORT const QStringList files( const QString &zip );
93+
8694
};
8795

8896
#endif //QGSZIPUTILS_H

‎tests/src/python/test_qgsziputils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,19 @@ def test_zip_unzip_ok(self):
121121
self.assertTrue(rc)
122122
self.assertEqual(len(files), 3)
123123

124+
def test_zip_files(self):
125+
zip = tmpPath()
126+
127+
f0 = os.path.join(unitTestDataPath(), 'multipoint.shp')
128+
f1 = os.path.join(unitTestDataPath(), 'lines.shp')
129+
f2 = os.path.join(unitTestDataPath(), 'joins.qgs')
130+
131+
rc = QgsZipUtils.zip(zip, [f0, f1, f2])
132+
self.assertTrue(rc)
133+
134+
files = QgsZipUtils.files(zip)
135+
self.assertEqual(files, ['multipoint.shp', 'lines.shp', 'joins.qgs'])
136+
124137

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

0 commit comments

Comments
 (0)
Please sign in to comment.