QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsarchive.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsarchive.cpp
3  ----------------
4 
5  begin : July 07, 2017
6  copyright : (C) 2017 by Paul Blottiere
7  email : [email protected]
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include "qgsarchive.h"
20 #include "qgsziputils.h"
21 #include "qgsmessagelog.h"
22 #include "qgsauxiliarystorage.h"
23 
24 
25 #ifdef Q_OS_WIN
26 #include <windows.h>
27 #endif
28 
29 #include <QStandardPaths>
30 #include <QUuid>
31 
33  : mDir( new QTemporaryDir() )
34 {
35 }
36 
38  : mFiles( other.mFiles )
39  , mDir( new QTemporaryDir() )
40 {
41 }
42 
44 {
45  if ( this != &other )
46  {
47  mFiles = other.mFiles;
48  mDir.reset( new QTemporaryDir() );
49  }
50 
51  return *this;
52 }
53 
54 QString QgsArchive::dir() const
55 {
56  return mDir->path();
57 }
58 
60 {
61  mDir.reset( new QTemporaryDir() );
62  mFiles.clear();
63 }
64 
65 bool QgsArchive::zip( const QString &filename )
66 {
67  const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
68  const QString uuid = QUuid::createUuid().toString();
69  QFile tmpFile( tempPath + QDir::separator() + uuid );
70 
71  // zip content
72  if ( ! QgsZipUtils::zip( tmpFile.fileName(), mFiles ) )
73  {
74  const QString err = QObject::tr( "Unable to zip content" );
75  QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
76  return false;
77  }
78 
79  // remove existing zip file
80  if ( QFile::exists( filename ) )
81  QFile::remove( filename );
82 
83 #ifdef Q_OS_WIN
84  // Clear temporary flag (see GH #32118)
85  DWORD dwAttrs;
86 #ifdef UNICODE
87  dwAttrs = GetFileAttributes( qUtf16Printable( tmpFile.fileName() ) );
88  SetFileAttributes( qUtf16Printable( tmpFile.fileName() ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
89 #else
90  dwAttrs = GetFileAttributes( tmpFile.fileName().toLocal8Bit( ).data( ) );
91  SetFileAttributes( tmpFile.fileName().toLocal8Bit( ).data( ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
92 #endif
93 
94 #endif // Q_OS_WIN
95 
96  // save zip archive
97  if ( ! tmpFile.rename( filename ) )
98  {
99  const QString err = QObject::tr( "Unable to save zip file '%1'" ).arg( filename );
100  QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
101  return false;
102  }
103 
104  return true;
105 }
106 
107 bool QgsArchive::unzip( const QString &filename )
108 {
109  clear();
110  return QgsZipUtils::unzip( filename, mDir->path(), mFiles );
111 }
112 
113 void QgsArchive::addFile( const QString &file )
114 {
115  mFiles.append( file );
116 }
117 
118 bool QgsArchive::removeFile( const QString &file )
119 {
120  bool rc = false;
121 
122  if ( !file.isEmpty() && mFiles.contains( file ) && QFile::exists( file ) )
123  rc = QFile::remove( file );
124 
125  mFiles.removeOne( file );
126 
127  return rc;
128 }
129 
130 QStringList QgsArchive::files() const
131 {
132  return mFiles;
133 }
134 
135 bool QgsArchive::exists() const
136 {
137  return QFileInfo::exists( mDir->path() );
138 }
139 
141 {
142  const auto constFiles = files();
143  for ( const QString &file : constFiles )
144  {
145  const QFileInfo fileInfo( file );
146  if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 )
147  return file;
148  }
149 
150  return QString();
151 }
152 
153 bool QgsProjectArchive::unzip( const QString &filename )
154 {
155  if ( QgsArchive::unzip( filename ) )
156  return ! projectFile().isEmpty();
157  else
158  return false;
159 }
160 
162 {
163  return removeFile( projectFile() );
164 }
165 
167 {
168  const QString extension = QgsAuxiliaryStorage::extension();
169 
170  const QStringList fileList = files();
171  for ( const QString &file : fileList )
172  {
173  const QFileInfo fileInfo( file );
174  if ( fileInfo.suffix().compare( extension, Qt::CaseInsensitive ) == 0 )
175  return file;
176  }
177 
178  return QString();
179 }
Class allowing to manage the zip/unzip actions.
Definition: qgsarchive.h:35
QgsArchive()
Constructor.
Definition: qgsarchive.cpp:32
QgsArchive & operator=(const QgsArchive &other)
Definition: qgsarchive.cpp:43
virtual bool unzip(const QString &zipFilename)
Clear the current content of this archive and unzip.
Definition: qgsarchive.cpp:107
bool zip(const QString &zipFilename)
Zip the content of this archive.
Definition: qgsarchive.cpp:65
void clear()
Clear the current content of this archive and create a new temporary directory.
Definition: qgsarchive.cpp:59
bool exists() const
Returns true if the archive exists on the filesystem, false otherwise.
Definition: qgsarchive.cpp:135
void addFile(const QString &filename)
Add a new file to this archive.
Definition: qgsarchive.cpp:113
bool removeFile(const QString &filename)
Remove a file from this archive and from the filesystem.
Definition: qgsarchive.cpp:118
QString dir() const
Returns the current temporary directory.
Definition: qgsarchive.cpp:54
QStringList files() const
Returns the list of files within this archive.
Definition: qgsarchive.cpp:130
static QString extension()
Returns the extension used for auxiliary databases.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
Definition: qgsarchive.cpp:140
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage file or an empty string if there's none.
Definition: qgsarchive.cpp:166
bool clearProjectFile()
Remove the current .qgs project file from the temporary directory.
Definition: qgsarchive.cpp:161
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
Definition: qgsarchive.cpp:153
CORE_EXPORT bool zip(const QString &zip, const QStringList &files)
Zip the list of files in the zip file.
CORE_EXPORT bool unzip(const QString &zip, const QString &dir, QStringList &files, bool checkConsistency=true)
Unzip a zip file in an output directory.
Definition: qgsziputils.cpp:37