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 "backup.h" |
20 | #include "global.h" |
21 | |
22 | #include <KDebug> |
23 | #include <KIO/NetAccess> |
24 | #include <KProcess> |
25 | #include <KStandardDirs> |
26 | #include <KTempDir> |
27 | #include <KUrl> |
28 | |
29 | #include <QDir> |
30 | |
31 | #include <akonadi/private/xdgbasedirs_p.h> |
32 | #include <akonadi/agentmanager.h> |
33 | |
34 | |
35 | using namespace Akonadi; |
36 | |
37 | /** |
38 | * Use this class to create a backup. possible() will tell you if all |
39 | * apps needed for the backup are available. Don't proceed without them. |
40 | * After that call create() to get it running. Please make sure the parameter |
41 | * has the tar.bz2 extension. |
42 | */ |
43 | Backup::Backup( QWidget *parent ) : QWidget( parent ) |
44 | { |
45 | } |
46 | |
47 | bool Backup::possible() |
48 | { |
49 | Tray::Global global; |
50 | QString dbDumpAppName; |
51 | if( global.dbdriver() == QLatin1String("QPSQL" ) ) |
52 | dbDumpAppName = QLatin1String("pg_dump" ); |
53 | else if( global.dbdriver() == QLatin1String("QMYSQL" ) ) |
54 | dbDumpAppName = QLatin1String("mysqldump" ); |
55 | else { |
56 | kError() << "Could not find an application to dump the database." ; |
57 | } |
58 | |
59 | m_dbDumpApp = KStandardDirs::findExe( dbDumpAppName ); |
60 | const QString bzip2 = KStandardDirs::findExe( QLatin1String("bzip2" ) ); |
61 | const QString tar = KStandardDirs::findExe( QLatin1String("tar" ) ); |
62 | kDebug() << "m_dbDumpApp:" << m_dbDumpApp << "bzip2:" << bzip2 << "tar:" << tar; |
63 | return !m_dbDumpApp.isEmpty() && !bzip2.isEmpty() && !tar.isEmpty(); |
64 | } |
65 | |
66 | void Backup::create( const KUrl& filename ) |
67 | { |
68 | if ( filename.isEmpty() ) { |
69 | emit completed( false ); |
70 | return; |
71 | } |
72 | |
73 | const QString sep( QDir::separator() ); |
74 | /* first create the temp folder. */ |
75 | KTempDir *tempDir = new KTempDir( KStandardDirs::locateLocal( "tmp" , QLatin1String("akonadi" ) ) ); |
76 | tempDir->setAutoRemove( false ); |
77 | KIO::NetAccess::mkdir( QString(tempDir->name() + QLatin1String("kdeconfig" )), this ); |
78 | KIO::NetAccess::mkdir( QString(tempDir->name() + QLatin1String("akonadiconfig" )), this ); |
79 | KIO::NetAccess::mkdir( QString(tempDir->name() + QLatin1String("db" )), this ); |
80 | |
81 | QStringList filesToBackup; |
82 | |
83 | /* Copy over the KDE config files. */ |
84 | AgentManager *manager = AgentManager::self(); |
85 | const AgentInstance::List list = manager->instances(); |
86 | foreach( const AgentInstance &agent, list ) { |
87 | const QString agentFileName = agent.identifier() + QLatin1String("rc" ); |
88 | const QString configFileName = KStandardDirs::locateLocal( "config" , agentFileName ); |
89 | bool exists = KIO::NetAccess::exists( configFileName, KIO::NetAccess::DestinationSide, this ); |
90 | if ( exists ) { |
91 | KIO::NetAccess::file_copy( configFileName, |
92 | QString(tempDir->name() + QLatin1String("kdeconfig" ) + sep + agentFileName), this ); |
93 | filesToBackup << QLatin1String("kdeconfig" ) + sep + agentFileName; |
94 | } |
95 | } |
96 | |
97 | /* Copy over the Akonadi config files */ |
98 | const QString config = XdgBaseDirs::findResourceDir( "config" , QLatin1String("akonadi" ) ); |
99 | QDir dir( config ); |
100 | const QStringList configlist = dir.entryList( QDir::Files ); |
101 | foreach( const QString& item, configlist ) { |
102 | KIO::NetAccess::file_copy( QString(config + sep + item), |
103 | QString(tempDir->name() + QLatin1String("akonadiconfig" ) + sep + item), this ); |
104 | filesToBackup << QLatin1String("akonadiconfig/" ) + item; |
105 | } |
106 | |
107 | /* Dump the database */ |
108 | Tray::Global global; |
109 | KProcess *proc = new KProcess( this ); |
110 | QStringList params; |
111 | |
112 | if( global.dbdriver() == QLatin1String("QMYSQL" ) ) { |
113 | params << QLatin1String("--single-transaction" ) |
114 | << QLatin1String("--flush-logs" ) |
115 | << QLatin1String("--triggers" ) |
116 | << QLatin1String("--result-file=" ) + tempDir->name() + QLatin1String("db" ) + sep + QLatin1String("database.sql" ) |
117 | << global.dboptions() |
118 | << global.dbname(); |
119 | } |
120 | else if ( global.dbdriver() == QLatin1String("QPSQL" ) ) { |
121 | params << QLatin1String("--format=custom" ) |
122 | << QLatin1String("--blobs" ) |
123 | << QLatin1String("--file=" ) + tempDir->name() + QLatin1String("db" ) + sep + QLatin1String("database.sql" ) |
124 | << global.dboptions() |
125 | << global.dbname(); |
126 | } |
127 | |
128 | kDebug() << "Executing: " << m_dbDumpApp << params; |
129 | proc->setProgram( m_dbDumpApp, params ); |
130 | int result = proc->execute(); |
131 | delete proc; |
132 | if ( result != 0 ) { |
133 | kWarning() << "Executed: " << m_dbDumpApp << params << "Result: " << result; |
134 | tempDir->unlink(); |
135 | delete tempDir; |
136 | emit completed( false ); |
137 | return; |
138 | } |
139 | filesToBackup << QLatin1String("db" ) + sep + QLatin1String("database.sql" ); |
140 | |
141 | /* Make a nice tar file. */ |
142 | proc = new KProcess( this ); |
143 | params.clear(); |
144 | params << QLatin1String("-C" ) << tempDir->name(); |
145 | params << QLatin1String("-cjf" ); |
146 | params << filename.toLocalFile() << filesToBackup; |
147 | proc->setWorkingDirectory( tempDir->name() ); |
148 | proc->setProgram( KStandardDirs::findExe( QLatin1String("tar" ) ), params ); |
149 | result = proc->execute(); |
150 | delete proc; |
151 | if ( result != 0 ) { |
152 | kWarning() << "Executed: " << KStandardDirs::findExe( QLatin1String("tar" ) ) << params << QLatin1String("Result: " ) << result; |
153 | tempDir->unlink(); |
154 | delete tempDir; |
155 | emit completed( false ); |
156 | return; |
157 | } |
158 | |
159 | tempDir->unlink(); |
160 | delete tempDir; |
161 | emit completed( true ); |
162 | } |
163 | |
164 | |