Add utilities functions for zip support

This commit is contained in:
Blottiere Paul 2017-07-07 21:06:22 +02:00
parent 5eba29e743
commit 7c85b200e6
5 changed files with 281 additions and 0 deletions

View File

@ -127,6 +127,7 @@
%Include qgsvirtuallayerdefinitionutils.sip %Include qgsvirtuallayerdefinitionutils.sip
%Include qgsmapthemecollection.sip %Include qgsmapthemecollection.sip
%Include qgsxmlutils.sip %Include qgsxmlutils.sip
%Include qgsziputils.sip
%Include qgsvector.sip %Include qgsvector.sip
%Include auth/qgsauthcertutils.sip %Include auth/qgsauthcertutils.sip
%Include auth/qgsauthconfig.sip %Include auth/qgsauthconfig.sip

View File

@ -0,0 +1,48 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsziputils.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
%ModuleHeaderCode
#include "qgsziputils.h"
%End
namespace QgsZipUtils
{
bool unzip( const QString &zip, const QString &dir, QStringList &files /Out/ );
%Docstring
Unzip a zip file in an output directory. An error is returned if the zip
filename does not exist, the output directory does not exist or is
not writable.
\param zip The zip filename
\param dir The output directory
\param files The absolute path of unzipped files
.. versionadded:: 3.0
:rtype: bool
%End
bool zip( const QString &zip, const QStringList &files );
%Docstring
Zip the list of files in the zip file. If the zip file yet exists or is
empty, an error is returned. If an input file does not exist, an error is
also returned.
\param zip The zip filename
\param files The absolute path filles to embed within the zip
.. versionadded:: 3.0
:rtype: bool
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsziputils.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -305,6 +305,7 @@ SET(QGIS_CORE_SRCS
qgsxmlutils.cpp qgsxmlutils.cpp
qgssettings.cpp qgssettings.cpp
qgsstacktrace.cpp qgsstacktrace.cpp
qgsziputils.cpp
composer/qgsaddremoveitemcommand.cpp composer/qgsaddremoveitemcommand.cpp
composer/qgsaddremovemultiframecommand.cpp composer/qgsaddremovemultiframecommand.cpp
@ -892,6 +893,7 @@ SET(QGIS_CORE_HDRS
qgsvirtuallayerdefinitionutils.h qgsvirtuallayerdefinitionutils.h
qgsmapthemecollection.h qgsmapthemecollection.h
qgsxmlutils.h qgsxmlutils.h
qgsziputils.h
qgsvector.h qgsvector.h
qgslocalec.h qgslocalec.h
@ -1218,6 +1220,7 @@ TARGET_LINK_LIBRARIES(qgis_core
${EXPAT_LIBRARY} ${EXPAT_LIBRARY}
${SQLITE3_LIBRARY} ${SQLITE3_LIBRARY}
${SPATIALITE_LIBRARY} ${SPATIALITE_LIBRARY}
${LIBZIP_LIBRARY}
) )
IF (Qt5Positioning_FOUND) IF (Qt5Positioning_FOUND)

177
src/core/qgsziputils.cpp Normal file
View File

@ -0,0 +1,177 @@
/***************************************************************************
qgsziputils.cpp
---------------------
begin : Jul 2017
copyright : (C) 2017 by Paul Blottiere
email : paul.blottiere@oslandia.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <fstream>
#include <QFileInfo>
#include <QDir>
#include "zip.h"
#include "qgsmessagelog.h"
#include "qgsziputils.h"
#include <iostream>
bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QStringList &files )
{
files.clear();
if ( !QFileInfo::exists( zipFilename ) )
{
QString err = QObject::tr( "Error zip file does not exist: '%1'" ).arg( zipFilename );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
else if ( zipFilename.isEmpty() )
{
QString err = QObject::tr( "Error zip filename is empty" );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
else if ( !QDir( dir ).exists( dir ) )
{
QString err = QObject::tr( "Error output dir does not exist: '%1'" ).arg( dir );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
else if ( !QFileInfo( dir ).isDir() )
{
QString err = QObject::tr( "Error output dir is not a directory: '%1'" ).arg( dir );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
else if ( !QFileInfo( dir ).isWritable() )
{
QString err = QObject::tr( "Error output dir is not writable: '%1'" ).arg( dir );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
int rc = 0;
struct zip *z = zip_open( zipFilename.toStdString().c_str(), ZIP_CHECKCONS, &rc );
if ( rc == ZIP_ER_OK && z != NULL )
{
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 );
size_t len = stat.size;
struct zip_file *file = zip_fopen_index( z, i, 0 );
char *buf = new char[len];
if ( zip_fread( file, buf, len ) != -1 )
{
QFileInfo newFile( QDir( dir ), QString( stat.name ) );
std::ofstream( newFile.absoluteFilePath().toStdString() ).write( buf, len );
zip_fclose( file );
files.append( newFile.absoluteFilePath() );
}
else
{
zip_fclose( file );
QString err = QObject::tr( "Error reading file: '%1'" ).arg( zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
}
}
else
{
zip_close( z );
QString err = QObject::tr( "Error getting files: '%1'" ).arg( zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
zip_close( z );
}
else
{
QString err = QObject::tr( "Error opening zip archive: '%1'" ).arg( zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
return true;
}
bool QgsZipUtils::zip( const QString &zipFilename, const QStringList &files )
{
if ( QFileInfo::exists( zipFilename ) )
{
QString err = QObject::tr( "Error zip file yet exist: '%1'" ).arg( zipFilename );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
else if ( zipFilename.isEmpty() )
{
QString err = QObject::tr( "Error zip filename is empty" );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
int rc = 0;
struct zip *z = zip_open( zipFilename.toStdString().c_str(), ZIP_CREATE, &rc );
if ( rc == ZIP_ER_OK && z != NULL )
{
Q_FOREACH ( QString file, files )
{
QFileInfo fileInfo( file );
if ( !fileInfo.exists() )
{
QString err = QObject::tr( "Error input file does not exist: '%1'" ).arg( file );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
zip_close( z );
}
zip_source *src = zip_source_file( z, file.toStdString().c_str(), 0, 0 );
if ( src != NULL )
{
if ( zip_file_add( z, fileInfo.fileName().toStdString().c_str(), src, 0 ) == -1 )
{
QString err = QObject::tr( "Error adding file: '%1'" ).arg( zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
zip_close( z );
return false;
}
}
else
{
QString err = QObject::tr( "Error creating data source: '%1'" ).arg( zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
zip_close( z );
return false;
}
}
zip_close( z );
}
else
{
QString err = QObject::tr( "Error creating zip archive: '%1'" ).arg( zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
return true;
}

52
src/core/qgsziputils.h Normal file
View File

@ -0,0 +1,52 @@
/***************************************************************************
qgsziputils.h
---------------------
begin : Jul 2017
copyright : (C) 2017 by Paul Blottiere
email : paul.blottiere@oslandia.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSZIPUTILS_H
#define QGSZIPUTILS_H
#include "qgis_core.h"
#include "qgis.h"
#include <QStringList>
#ifdef SIP_RUN
% ModuleHeaderCode
#include "qgsziputils.h"
% End
#endif
namespace QgsZipUtils
{
/** Unzip a zip file in an output directory. An error is returned if the zip
* filename does not exist, the output directory does not exist or is
* not writable.
* \param zip The zip filename
* \param dir The output directory
* \param files The absolute path of unzipped files
* \since QGIS 3.0
*/
CORE_EXPORT bool unzip( const QString &zip, const QString &dir, QStringList &files SIP_OUT );
/** Zip the list of files in the zip file. If the zip file yet exists or is
* empty, an error is returned. If an input file does not exist, an error is
* also returned.
* \param zip The zip filename
* \param files The absolute path filles to embed within the zip
* \since QGIS 3.0
*/
CORE_EXPORT bool zip( const QString &zip, const QStringList &files );
};
#endif //QGSZIPUTILS_H