QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
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
21#include "qgsauxiliarystorage.h"
22#include "qgsmessagelog.h"
23#include "qgsziputils.h"
24
25#ifdef Q_OS_WIN
26#include <windows.h>
27#endif
28
29#include <QStandardPaths>
30#include <QUuid>
31#include <memory>
32
34 : mDir( new QTemporaryDir() )
35{
36}
37
39 : mFiles( other.mFiles )
40 , mDir( new QTemporaryDir() )
41{
42}
43
45{
46 if ( this != &other )
47 {
48 mFiles = other.mFiles;
49 mDir = std::make_unique<QTemporaryDir>( );
50 }
51
52 return *this;
53}
54
55QString QgsArchive::dir() const
56{
57 return mDir->path();
58}
59
61{
62 mDir = std::make_unique<QTemporaryDir>( );
63 mFiles.clear();
64}
65
66bool QgsArchive::zip( const QString &filename )
67{
68 const QString tempPath( QDir::temp().absoluteFilePath( QStringLiteral( "qgis-project-XXXXXX.zip" ) ) );
69
70 // zip content
71 if ( ! QgsZipUtils::zip( tempPath, mFiles, true ) )
72 {
73 const QString err = QObject::tr( "Unable to zip content" );
74 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
75 return false;
76 }
77
78 QString target {filename};
79
80 // remove existing zip file
81 if ( QFile::exists( target ) )
82 {
83 // If symlink -> we want to write to its target instead
84 const QFileInfo targetFileInfo( target );
85 target = targetFileInfo.canonicalFilePath();
86 // If target still exists, remove (might not exist if was a dangling symlink)
87 if ( QFile::exists( target ) )
88 QFile::remove( target );
89 }
90
91#ifdef Q_OS_WIN
92 // Clear temporary flag (see GH #32118)
93 DWORD dwAttrs;
94#ifdef UNICODE
95 dwAttrs = GetFileAttributes( qUtf16Printable( tempPath ) );
96 SetFileAttributes( qUtf16Printable( tempPath ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
97#else
98 dwAttrs = GetFileAttributes( tempPath.toLocal8Bit( ).data( ) );
99 SetFileAttributes( tempPath.toLocal8Bit( ).data( ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
100#endif
101
102#endif // Q_OS_WIN
103
104 // save zip archive
105 if ( !QFile::rename( tempPath, target ) )
106 {
107 const QString err = QObject::tr( "Unable to save zip file '%1'" ).arg( target );
108 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
109 return false;
110 }
111
112 return true;
113}
114
115bool QgsArchive::unzip( const QString &filename )
116{
117 clear();
118 return QgsZipUtils::unzip( filename, mDir->path(), mFiles );
119}
120
121void QgsArchive::addFile( const QString &file )
122{
123 mFiles.append( file );
124}
125
126bool QgsArchive::removeFile( const QString &file )
127{
128 bool rc = false;
129
130 if ( !file.isEmpty() && mFiles.contains( file ) && QFile::exists( file ) )
131 rc = QFile::remove( file );
132
133 mFiles.removeOne( file );
134
135 return rc;
136}
137
138QStringList QgsArchive::files() const
139{
140 return mFiles;
141}
142
144{
145 return QFileInfo::exists( mDir->path() );
146}
147
149{
150 const auto constFiles = files();
151 for ( const QString &file : constFiles )
152 {
153 const QFileInfo fileInfo( file );
154 if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 )
155 return file;
156 }
157
158 return QString();
159}
160
161bool QgsProjectArchive::unzip( const QString &filename )
162{
163 if ( QgsArchive::unzip( filename ) )
164 return ! projectFile().isEmpty();
165 else
166 return false;
167}
168
173
175{
176 const QString extension = QgsAuxiliaryStorage::extension();
177
178 const QStringList fileList = files();
179 for ( const QString &file : fileList )
180 {
181 const QFileInfo fileInfo( file );
182 if ( fileInfo.suffix().compare( extension, Qt::CaseInsensitive ) == 0 )
183 return file;
184 }
185
186 return QString();
187}
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.