Skip to content
Permalink
Browse files

Add utilities functions for zip support

  • Loading branch information
pblottiere committed Jul 7, 2017
1 parent 5eba29e commit 7c85b200e6765095faa994451dacf285fef73dd8
Showing with 281 additions and 0 deletions.
  1. +1 −0 python/core/core_auto.sip
  2. +48 −0 python/core/qgsziputils.sip
  3. +3 −0 src/core/CMakeLists.txt
  4. +177 −0 src/core/qgsziputils.cpp
  5. +52 −0 src/core/qgsziputils.h
@@ -127,6 +127,7 @@
%Include qgsvirtuallayerdefinitionutils.sip
%Include qgsmapthemecollection.sip
%Include qgsxmlutils.sip
%Include qgsziputils.sip
%Include qgsvector.sip
%Include auth/qgsauthcertutils.sip
%Include auth/qgsauthconfig.sip
@@ -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 *
************************************************************************/
@@ -305,6 +305,7 @@ SET(QGIS_CORE_SRCS
qgsxmlutils.cpp
qgssettings.cpp
qgsstacktrace.cpp
qgsziputils.cpp

composer/qgsaddremoveitemcommand.cpp
composer/qgsaddremovemultiframecommand.cpp
@@ -892,6 +893,7 @@ SET(QGIS_CORE_HDRS
qgsvirtuallayerdefinitionutils.h
qgsmapthemecollection.h
qgsxmlutils.h
qgsziputils.h
qgsvector.h
qgslocalec.h

@@ -1218,6 +1220,7 @@ TARGET_LINK_LIBRARIES(qgis_core
${EXPAT_LIBRARY}
${SQLITE3_LIBRARY}
${SPATIALITE_LIBRARY}
${LIBZIP_LIBRARY}
)

IF (Qt5Positioning_FOUND)
@@ -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;
}
@@ -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

0 comments on commit 7c85b20

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