1/* This file is part of the KDE project
2 Copyright (C) 2008 Omat Holding B.V. <info@omat.nl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17*/
18
19#include "restore.h"
20#include "global.h"
21
22#include <KDebug>
23#include <KProcess>
24#include <KStandardDirs>
25#include <KTempDir>
26#include <KUrl>
27
28#include <QDir>
29
30#include <kio/netaccess.h>
31
32#include <akonadi/private/xdgbasedirs_p.h>
33
34
35using namespace Akonadi;
36
37/**
38 * Use this class to restore a backup. possible() will tell you if all
39 * apps needed for the restore are available. Don't proceed without them.
40 * After that call restore() to get it running. Please make sure the parameter
41 * has the tar.bz2 extension.
42 */
43Restore::Restore( QWidget *parent ) : QWidget( parent )
44{
45}
46
47bool Restore::possible()
48{
49 Tray::Global global;
50 QString dbRestoreAppName;
51 if( global.dbdriver() == QLatin1String("QPSQL") )
52 dbRestoreAppName = QLatin1String("pg_restore");
53 else if( global.dbdriver() == QLatin1String("QMYSQL") )
54 dbRestoreAppName = QLatin1String("mysql");
55 else {
56 kError() << "Could not find an application to restore the database.";
57 }
58
59 m_dbRestoreApp = KStandardDirs::findExe( dbRestoreAppName );
60 const QString bzip2 = KStandardDirs::findExe( QLatin1String("bzip2") );
61 const QString tar = KStandardDirs::findExe( QLatin1String("tar") );
62 kDebug() << "m_dbRestoreApp:" << m_dbRestoreApp << "bzip2:" << bzip2 << "tar:" << tar;
63 return !m_dbRestoreApp.isEmpty() && !bzip2.isEmpty() && !tar.isEmpty();
64}
65
66void Restore::restore( const KUrl& filename )
67{
68 if ( filename.isEmpty() ) {
69 emit completed( false );
70 return;
71 }
72
73 const QString sep = QDir::separator();
74
75 /* first create the temp folder. */
76 KTempDir *tempDir = new KTempDir( KStandardDirs::locateLocal( "tmp", QLatin1String("akonadi") ) );
77 tempDir->setAutoRemove( false );
78 kDebug() << "Temp dir: "<< tempDir->name();
79
80 /* Extract the nice tar file. */
81 KProcess *proc = new KProcess( this );
82 QStringList params;
83 params << QLatin1String("-C") << tempDir->name();
84 params << QLatin1String("-xjf");
85 params << filename.toLocalFile();
86 proc->setWorkingDirectory( tempDir->name() );
87 proc->setProgram( KStandardDirs::findExe( QLatin1String("tar") ), params );
88 int result = proc->execute();
89 delete proc;
90 if ( result != 0 ) {
91 kWarning() << "Executed:" << KStandardDirs::findExe( QLatin1String("tar") ) << params << " Result: " << result;
92 tempDir->unlink();
93 delete tempDir;
94 emit completed( false );
95 return;
96 }
97
98 /* Copy over the KDE configuration files. */
99 QDir dir( tempDir->name() + QLatin1String("kdeconfig") + sep );
100 dir.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
101 QFileInfoList list = dir.entryInfoList();
102 const int numberOfElement = list.size();
103 for ( int i = 0; i < numberOfElement; ++i ) {
104 QFileInfo fileInfo = list.at( i );
105 const QString source = fileInfo.absoluteFilePath();
106 const QString dest = KStandardDirs::locateLocal( "config", fileInfo.fileName() );
107
108 kDebug() << "Restoring: " << source << "to:" << dest;
109 KIO::NetAccess::file_copy( source, dest, this );
110 }
111
112 /* Copy over the Akonadi configuration files. */
113 const QString akonadiconfigfolder = XdgBaseDirs::findResourceDir( "config", QLatin1String("akonadi") );
114 dir.setPath( tempDir->name() + QLatin1String("akonadiconfig") + sep );
115 dir.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
116 list = dir.entryInfoList();
117 const int sizeOfList = list.size();
118 for ( int i = 0; i < sizeOfList; ++i ) {
119 QFileInfo fileInfo = list.at( i );
120 const QString source = fileInfo.absoluteFilePath();
121 const QString dest = akonadiconfigfolder + sep + fileInfo.fileName();
122
123 kDebug() << "Restoring: " << source << "to:" << dest;
124 KIO::NetAccess::file_copy( source, dest, this );
125 }
126
127 /* Restore the database */
128 Tray::Global global;
129 proc = new KProcess( this );
130 params.clear();
131
132 if( global.dbdriver() == QLatin1String("QPSQL") ) {
133 params << global.dboptions()
134 << QLatin1String("--dbname=") + global.dbname()
135 << QLatin1String("--format=custom")
136 << QLatin1String("--clean")
137 << QLatin1String("--no-owner")
138 << QLatin1String("--no-privileges")
139 << tempDir->name() + QLatin1String("db") + sep + QLatin1String("database.sql");
140 }
141 else if (global.dbdriver() == QLatin1String("QMYSQL") ) {
142 params << global.dboptions()
143 << QLatin1String("--database=") + global.dbname();
144 }
145
146 kDebug() << "Executing:" << m_dbRestoreApp << params;
147 ;
148 proc->setProgram( KStandardDirs::findExe( m_dbRestoreApp ), params );
149 proc->setStandardInputFile(tempDir->name() + QLatin1String("db") + sep + QLatin1String("database.sql"));
150 result = proc->execute();
151 delete proc;
152 if ( result != 0 ) {
153 kWarning() << "Executed:" << m_dbRestoreApp << params << " Result: " << result;
154 tempDir->unlink();
155 delete tempDir;
156 emit completed( false );
157 return;
158 }
159
160 tempDir->unlink();
161 delete tempDir;
162 emit completed( true );
163}
164
165