QGIS API Documentation 3.43.0-Master (58029bba303)
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 : paul.blottiere@oslandia.com
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
54QString QgsArchive::dir() const
55{
56 return mDir->path();
57}
58
60{
61 mDir.reset( new QTemporaryDir() );
62 mFiles.clear();
63}
64
65bool QgsArchive::zip( const QString &filename )
66{
67 const QString tempPath( QDir::temp().absoluteFilePath( QStringLiteral( "qgis-project-XXXXXX.zip" ) ) );
68
69 // zip content
70 if ( ! QgsZipUtils::zip( tempPath, mFiles, true ) )
71 {
72 const QString err = QObject::tr( "Unable to zip content" );
73 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
74 return false;
75 }
76
77 QString target {filename};
78
79 // remove existing zip file
80 if ( QFile::exists( target ) )
81 {
82 // If symlink -> we want to write to its target instead
83 const QFileInfo targetFileInfo( target );
84 target = targetFileInfo.canonicalFilePath();
85 // If target still exists, remove (might not exist if was a dangling symlink)
86 if ( QFile::exists( target ) )
87 QFile::remove( target );
88 }
89
90#ifdef Q_OS_WIN
91 // Clear temporary flag (see GH #32118)
92 DWORD dwAttrs;
93#ifdef UNICODE
94 dwAttrs = GetFileAttributes( qUtf16Printable( tempPath ) );
95 SetFileAttributes( qUtf16Printable( tempPath ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
96#else
97 dwAttrs = GetFileAttributes( tempPath.toLocal8Bit( ).data( ) );
98 SetFileAttributes( tempPath.toLocal8Bit( ).data( ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
99#endif
100
101#endif // Q_OS_WIN
102
103 // save zip archive
104 if ( !QFile::rename( tempPath, target ) )
105 {
106 const QString err = QObject::tr( "Unable to save zip file '%1'" ).arg( target );
107 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
108 return false;
109 }
110
111 return true;
112}
113
114bool QgsArchive::unzip( const QString &filename )
115{
116 clear();
117 return QgsZipUtils::unzip( filename, mDir->path(), mFiles );
118}
119
120void QgsArchive::addFile( const QString &file )
121{
122 mFiles.append( file );
123}
124
125bool QgsArchive::removeFile( const QString &file )
126{
127 bool rc = false;
128
129 if ( !file.isEmpty() && mFiles.contains( file ) && QFile::exists( file ) )
130 rc = QFile::remove( file );
131
132 mFiles.removeOne( file );
133
134 return rc;
135}
136
137QStringList QgsArchive::files() const
138{
139 return mFiles;
140}
141
143{
144 return QFileInfo::exists( mDir->path() );
145}
146
148{
149 const auto constFiles = files();
150 for ( const QString &file : constFiles )
151 {
152 const QFileInfo fileInfo( file );
153 if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 )
154 return file;
155 }
156
157 return QString();
158}
159
160bool QgsProjectArchive::unzip( const QString &filename )
161{
162 if ( QgsArchive::unzip( filename ) )
163 return ! projectFile().isEmpty();
164 else
165 return false;
166}
167
172
174{
175 const QString extension = QgsAuxiliaryStorage::extension();
176
177 const QStringList fileList = files();
178 for ( const QString &file : fileList )
179 {
180 const QFileInfo fileInfo( file );
181 if ( fileInfo.suffix().compare( extension, Qt::CaseInsensitive ) == 0 )
182 return file;
183 }
184
185 return QString();
186}
Manages zip/unzip operations for an archive.
Definition qgsarchive.h:35
QgsArchive & operator=(const QgsArchive &other)
virtual bool unzip(const QString &zipFilename)
Clear the current content of this archive and unzip.
bool zip(const QString &zipFilename)
Zip the content of this archive.
void clear()
Clear the current content of this archive and create a new temporary directory.
bool exists() const
Returns true if the archive exists on the filesystem, false otherwise.
void addFile(const QString &filename)
Add a new file to this archive.
bool removeFile(const QString &filename)
Remove a file from this archive and from the filesystem.
QString dir() const
Returns the current temporary directory.
QStringList files() const
Returns the list of files within this archive.
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
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.
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage file or an empty string if there's none.
bool clearProjectFile()
Remove the current .qgs project file from the temporary directory.
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
static bool zip(const QString &zip, const QStringList &files, bool overwrite=false)
Zip the list of files in the zip file.
static bool unzip(const QString &zip, const QString &dir, QStringList &files, bool checkConsistency=true)
Unzip a zip file in an output directory.