QGIS API Documentation 3.41.0-Master (64d82d4c163)
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
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 = 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 QString target {filename};
80
81 // remove existing zip file
82 if ( QFile::exists( target ) )
83 {
84 // If symlink -> we want to write to its target instead
85 const QFileInfo targetFileInfo( target );
86 target = targetFileInfo.canonicalFilePath();
87 // If target still exists, remove (might not exist if was a dangling symlink)
88 if ( QFile::exists( target ) )
89 QFile::remove( target );
90 }
91
92#ifdef Q_OS_WIN
93 // Clear temporary flag (see GH #32118)
94 DWORD dwAttrs;
95#ifdef UNICODE
96 dwAttrs = GetFileAttributes( qUtf16Printable( tmpFile.fileName() ) );
97 SetFileAttributes( qUtf16Printable( tmpFile.fileName() ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
98#else
99 dwAttrs = GetFileAttributes( tmpFile.fileName().toLocal8Bit( ).data( ) );
100 SetFileAttributes( tmpFile.fileName().toLocal8Bit( ).data( ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
101#endif
102
103#endif // Q_OS_WIN
104
105 // save zip archive
106 if ( ! tmpFile.rename( target ) )
107 {
108 const QString err = QObject::tr( "Unable to save zip file '%1'" ).arg( target );
109 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
110 return false;
111 }
112
113 return true;
114}
115
116bool QgsArchive::unzip( const QString &filename )
117{
118 clear();
119 return QgsZipUtils::unzip( filename, mDir->path(), mFiles );
120}
121
122void QgsArchive::addFile( const QString &file )
123{
124 mFiles.append( file );
125}
126
127bool QgsArchive::removeFile( const QString &file )
128{
129 bool rc = false;
130
131 if ( !file.isEmpty() && mFiles.contains( file ) && QFile::exists( file ) )
132 rc = QFile::remove( file );
133
134 mFiles.removeOne( file );
135
136 return rc;
137}
138
139QStringList QgsArchive::files() const
140{
141 return mFiles;
142}
143
145{
146 return QFileInfo::exists( mDir->path() );
147}
148
150{
151 const auto constFiles = files();
152 for ( const QString &file : constFiles )
153 {
154 const QFileInfo fileInfo( file );
155 if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 )
156 return file;
157 }
158
159 return QString();
160}
161
162bool QgsProjectArchive::unzip( const QString &filename )
163{
164 if ( QgsArchive::unzip( filename ) )
165 return ! projectFile().isEmpty();
166 else
167 return false;
168}
169
174
176{
177 const QString extension = QgsAuxiliaryStorage::extension();
178
179 const QStringList fileList = files();
180 for ( const QString &file : fileList )
181 {
182 const QFileInfo fileInfo( file );
183 if ( fileInfo.suffix().compare( extension, Qt::CaseInsensitive ) == 0 )
184 return file;
185 }
186
187 return QString();
188}
Class allowing to manage the zip/unzip actions.
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.
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.